← Back to articles

EF Core in separate project

Part of my ASP.NET Core recipe series: moving EF Core into its own project so the data layer stays separated from the web application.

Tedd

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

Written by Tedd · Oslo, Norway

Updated 27 Aug 2019

Follow the journal via RSS