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. For intance:
// Application compoment registered in and resolved from Simple Injector
public class CommentIsNoSpamValidator : IValidator<PostComment>
{
private readonly BloggingContext context;
// Is injected with BloggingContext from IServiceCollection
public CommentIsNoSpamValidator(BloggingContext context)
{
this.context = context;
}
public IEnumerable<ValidationResult> Validate(PostComment command)
{
// Complex business logic here.
}
}
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();
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.