Using Entity Framework Core DbContext Pooling with Simple Injector

dbcontext ef-core-2.1 entity-framework-core simple-injector

Question

Looking at the examples of how to use db context pool I see it was designed to be used with ServiceCollection:

var serviceProvider = new ServiceCollection()
    .AddDbContextPool<AdventureWorksContext>(options => { //options })
    .BuildServiceProvider();

But what about Simple Injector? is it possible to register DB pooling in the Simple Injector container?

p.s. My app is not ASP.NET MVC, it's just a kinda DAL

1
3
12/6/2018 8:35:40 AM

Popular Answer

EF Core DbContext pooling in ASP.NET Core

When integrating Simple Injector in ASP.NET Core, you keep framework and third-party components inside the .NET Core configuration system. This means that enabling Entity Framework Core context pooling is done exactly as Microsoft documents it:

services.AddDbContextPool<BloggingContext>(
    options => options.UseSqlServer(connectionString));

As Simple Injector does not replace the built-in configuration system, you will have to instruct Simple Injector to automatically load missing registrations (such as your DbContext) from the .NET Core configuration system. This can be done by using the AddSimpleInjector and UseSimpleInjector extension methods, as shown here.

private SimpleInjector.Container container;

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddDbContextPool<BloggingContext>(
        options => options.UseSqlServer(connectionString));        

    services.AddSimpleInjector(container, options =>
    {
        options.AddAspNetCore();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSimpleInjector(container);

    container.Verify();

    ...
}

Using this setup, the BloggingContext can be injected into any component that is resolved from Simple Injector, while the BloggingContext is pooled by Entity Framework.

EF Core DbContext pooling in a .NET (Core) Console application

When it comes to using Entity Framework Core context pooling in a .NET Core console application, the solution will be very similar, although you will have to set up a little bit more:

public void Main()
{
    var container = new Container();
    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

    var services = new ServiceCollection();

    services.AddDbContextPool<BloggingContext>(
            options => options.UseSqlServer(connectionString));

    services.AddSimpleInjector(container);

    services
        .BuildServiceProvider(validateScopes: true)
        .UseSimpleInjector(container);

    container.Verify();

    // Run application code
    using (AsyncScopedLifestyle.BeginScope(container))
    {
        var service = container.GetInstance<MainService>();
        service.DoAwesomeStuff();
    }
}

So in the end, the DbContext's lifetime is managed by the MS.DI scope, but that scope is managed by Simple Injector's scope.

EF Core DbContext pooling in a library

In case you are building a library, i.e. a non-startup project, please stop what you're doing. Only the application's startup assembly should have a Composition Root, and only the Composition Root should use a DI Container (such as Simple Injector or MS.DI's `ServiceCollection). All other libraries in your application should stay oblivious of the (possible) existence of a Container:

In case you use a DI Container, the Composition Root should be the only place where you use the DI Container. Using a DI Container outside the Composition Root leads to the Service Locator anti-pattern (source)

8
6/15/2019 1:29:41 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow