EF Core in separate project

Whether writing stand alone application or web application you may want to put database related code into a separate project. I find it good for separating concerns.

In a previous post I covered using .Net Core Generic Host for stand alone projects, but the same applies to ASP.Net Core applications as they also use Generic Host.

By database related code I mean things such as database context, table models and database related config.

Create project

Create a new Class Library. Usually this can be .NET Standard, but .NET Core will work just fine. If you plan to share project with .Net 4.x you may want to go with .NET Standard.

Installing

Make sure you have selected your new database-project.

Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.AspNetCore.Hosting.Abstractions
// Only required if you want to use IOptions
Install-Package Microsoft.Extensions.Options.ConfigurationExtensions

Create test database

TestElement.cs

public class TestElement
{
    public int Id { get; set; }
    public string Name { get; set; }
}

TestDbContext.cs

public class TestDbContext: DbContext
{
    //  public TestDbContext(DbContextOptions<TestDbContext> options)
    //: base(options)
    //  { }
    public DbSet<TestElement> TestElements { get; set; }
}

Adding new project to Startup.cs

Create a DatabaseStartup.cs that functions as you would normally expect from Startup.cs, but containing only database specific things:

//using Microsoft.AspNetCore.Builder;
//using Microsoft.AspNetCore.Hosting;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.Extensions.Configuration;
//using Microsoft.Extensions.DependencyInjection;

public static class DatabaseStartup
{
    private static IConfiguration _configuration;

    public static void SetConfig(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public static void ConfigureServices(IServiceCollection services)
    {
        var dbConnectionString = _configuration.GetValue<string>("Database:ConnectionString");
        services.AddDbContext<TestDbContext>(options => options.UseSqlServer(dbConnectionString), ServiceLifetime.Transient);
            
        // Optional. Requires Microsoft.Extensions.Options.ConfigurationExtensions
        services.Configure<DatabaseConfig>(_configuration.GetSection("Database"));
    }

    public static void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

Every method in Startup.cs should execute a corresponding method in DatabaseStartup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        // ...
        DatabaseStartup.SetConfig(configuration);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        DatabaseStartup.ConfigureServices(services);
    }

}

If you need config object for database registered then you also need to create DatabaseConfig.cs:

public class DatabaseConfig
{
    public string ConnectionString { get; set; }
}

Scaffolding & Migration

Install-Package Microsoft.EntityFrameworkCore.Tools

Add-Migration -Project Tedd.CoreWebExample.Database -StartupProject Tedd.CoreWebExample.WebUi “InitialMigration”

Update-Database -Project Tedd.CoreWebExample.Database -StartupProject Tedd.CoreWebExample.WebUi

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Tedds blog

Subscribe now to keep reading and get access to the full archive.

Continue reading