将实体框架核心DbContext池与简单注入器一起使用

use*_*399 2 simple-injector dbcontext entity-framework-core ef-core-2.1

查看有关如何使用数据库上下文池的示例,我发现它是设计用于ServiceCollection

var serviceProvider = new ServiceCollection()
    .AddDbContextPool<AdventureWorksContext>(options => { //options })
    .BuildServiceProvider();
Run Code Online (Sandbox Code Playgroud)

但是简单注入器呢?是否可以在Simple Injector容器中注册数据库池?

ps我的应用不是ASP.NET MVC,只是DAL

Ste*_*ven 6

ASP.NET Core中的EF Core DbContext池

在ASP.NET Core中集成Simple Injector时,会将框架和第三方组件保留在.NET Core配置系统中。这意味着启用Entity Framework Core上下文池的过程与Microsoft记录的完全相同:

services.AddDbContextPool<BloggingContext>(
    options => options.UseSqlServer(connectionString));
Run Code Online (Sandbox Code Playgroud)

由于Simple Injector 不能替代内置配置系统,因此您将必须指示 Simple Injector DbContext从.NET Core配置系统中自动加载缺少的注册信息(例如)。可以使用AddSimpleInjectorUseSimpleInjector扩展方法来完成,如下所示。

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();

    ...
}
Run Code Online (Sandbox Code Playgroud)

使用此设置,BloggingContext可以将其注入由Simple Injector解析的任何组件中,而BloggingContext则由Entity Framework合并。

.NET(核心)控制台应用程序中的EF Core DbContext池

在.NET Core控制台应用程序中使用Entity Framework Core上下文池时,解决方案将非常相似,尽管您将需要进行更多设置:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,最后,DbContext的生存期由MS.DI范围管理,但该范围由Simple Injector的范围管理。

库中的EF Core DbContext池

如果您正在构建一个库,即非启动项目,请停止正在做的事情。只有应用程序的启动程序集才应具有“ 合成根”,并且只有“合成根”应使用DI容器(例如,简单注入器或MS.DI的`ServiceCollection)。您的应用程序中的所有其他库都应忽略(可能)容器的存在:

如果使用DI容器,则“合成根”应该是唯一使用DI容器的地方。在合成根之外使用DI容器会导致“服务定位器”反模式(


Nei*_*oss 0

你可以使用

container.Register(() => serviceProvider.GetRequiredService<AdventureWorksContext>());

让 ServiceProvider 根据请求解决依赖关系。