简体   繁体   English

具有单例依赖注入的实体框架核心

[英]Entity Framework Core with dependency injection with singletons

I am trying to use Dependency Injection with a singleton and DBContext.我正在尝试将依赖注入与 singleton 和DBContext.

In .net framework I can do something like this在 .net 框架中我可以做这样的事情

public class MySingleton
{
    private readonly Func<MyDbContext> _getContext;
    public MySingleton(Func<MyDbContext> getContext)
    {
      _getContext = getContext;
    }
}

However, when I do this now I get the following error:但是,当我现在这样做时,出现以下错误:

Unable to resolve service for type 'System.Func`1[MyDbContext]'无法解析类型为“System.Func`1 [MyDbContext]”的服务

I did try to add this to the constructor.我确实尝试将其添加到构造函数中。

public class MySingleton
{
    private readonly Func<MyDbContext> _getContext;
    public MySingleton(IServiceProvider serviceProvider)
    {
         _getContext =
             () => (MyDbContext)serviceProvider.GetService(typeof(MyDbContext));
    }
}

However, serviceProvider returns the same instance但是, serviceProvider返回相同的实例

How can I create a new instance of MyDbContext every time I use it?每次使用MyDbContext时如何创建一个新实例?

When resolving a singleton with MS.DI, that singleton and all its dependencies are resolved from the root scope/container.当使用 MS.DI 解析 singleton 时,singleton及其所有依赖项都从根作用域/容器中解析。 This is why you experience the behavior where resolving the MyDbContext from an injected IServiceProvider always gives the same instance;这就是为什么您会遇到从注入的IServiceProvider解析MyDbContext总是给出相同实例的行为; that scoped instance is scoped to the container.该作用域实例的作用域为容器。 In other words, that scoped instance implicitly became a singleton.换句话说,该作用域实例隐式变为 singleton。

MS.DI's Closure Composition Model makes it very hard to resolve scopes within singletons (without manually managing scopes through ambient state), because scopes are not available ubiquitously through ambient state, as is done using the Ambient Composition Model . MS.DI 的Closure Composition Model使得在单例中解析范围变得非常困难(无需通过环境状态手动管理范围),因为范围并非通过环境 state 普遍可用,就像使用环境组合 Model所做的那样。

In practice, there are two options here:实际上,这里有两种选择:

  1. Either you shorten the lifestyle of your singleton component to either Transient or Scoped您可以将 singleton 组件的生命周期缩短为TransientScoped
  2. You start and manage an IServiceScope from within the component's methods and resolve the scoped component from such scope. For instance:您从组件的方法中启动和管理IServiceScope ,并从 scope 解析作用域组件。例如:
     public class MySingleton { private readonly IServiceProvider provider; public MySingleton(IServiceProvider provider) { this.provider = provider; } public void SomeMethod() { using (var scope = this.provider.CreateScope()) { scope.ServiceProvider.GetRequiredInstancce<MyDbContext>(); } } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM