Configuring EntityFramework for .NET Core

I will try to show some real example of .net core way of configuring Entity Framework Code First in this article. Microsoft documentation shows some examples, but the solution there creates one DbContext and stores it in DI container.

Downsize of that solution is that you cannot dispose container obtained from DI.

Better solution is to create a Factory class, store it as Singleton into Di container and create DbContext with this service.

public class MyDataContextFactory : IDataContextFactory
{
const string ConnectionStringName = "MyDbConn";
IConfigurationRoot configuration;
public DataContextFactory(IConfigurationRoot Configuration)
{
configuration = Configuration;
}
public DataContext Create()
{
var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(
configuration.GetConnectionString(ConnectionStringName));
return new MyDataContext(optionsBuilder.Options);
}
}

Also, for this class, we would create interface IMyDataContextFactory, which will look like this:

public interface IMyDataContextFactory
{
MyDataContext Create();
}

The meat of this class is the method Create, which reads from Configuration the Db connection string and creates particular instance of DbContext. In my case called MyDataContext. I am passing Sql connection string read from configuration.

The class is taking IConfigurationRoot as only parameter, so that it could read from .Net Core Configuration. This is usually appsettings.json, but its up to your application.

Configuration and registration of the service

When you look to your Program.cs, you can see it configured like for example this:

public class Program
{
public static IConfigurationRoot Configuration { get; set; }
public static void Main(string[] args = null)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
/// and so on...

Please notice Configuration is – when created to class member.
The next step is to add Factory method to .Net core dependency injection container. In the Startup.cs file, locate your existing ConfigureServices, which is used for these things and add our line for example to end of it:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Register MyDataContextFactory here
services.AddSingleton(
new DataContextFactory(Configuration));
}

How to use it in Controllers

The use is then similar to other Net Core DI services. We need to add our factory interface to particular Controller constructor, to get injected by DI automatically. It will look like this:

public class ValueController : Controller
{
private IMyDataContextFactory myDataContextFactory;
public ValueController(IMyDataContextFactory myDataContextFactory)
{
this.myDataContextFactory=myDataContextFactory;
}
// and so on

And use is then very simple, for example in same controller I can have method like:

public class ValueController : Controller
{
// ...
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
{
using (var context = dataContextFactory.Create())
{
var item = context.TodoItems.FirstOrDefault(t => t.Id == id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
// ...

So it is, hopefully this will help someone.

Thanks for reading.