Dou*_*oid 2 c# dependency-injection entity-framework-core asp.net-core-mvc asp.net-core
我正在使用SoapCore为我的 ASP.NET Core MVC 应用程序创建一个 Web 服务。
我正在使用 Entity Framework Core 和一个简单的 Repository 模式来获取我的数据库数据。
我正在通过.AddSingleton()Startup.cs注入我的存储库类:
services.AddSingleton<IImportRepository, ImportRepository>();
services.AddSingleton<IWebService, WebService>();
由于 EFDbContext是范围的,因此在调用我的 Web 服务时出现错误:
无法从单例“App._Repository.IImportRepository”使用范围服务“App.Data.ApplicationDbContext”。
当我使用.AddScoped()它时,它工作正常。
我读过通过控制器/类构造函数注入作用域依赖项是不好的做法,因为它“回退”为单例或表现得像一个。
我想知道是否有另一种方法可以使其与单身人士一起使用,或者从长远来看这是否有一些主要缺点(大约 100-200 个用户将使用该站点)通过 ctor 在我的控制器中使用范围注入?
简而言之,您的首选生命周期应该是“有范围的”。如果有充分的理由,您应该只使用单例或瞬态生命周期。对于单例,这就像管理锁或保存需要在应用程序的生命周期内持续存在的数据之类的东西,这两者都不适用于存储库的概念。存储库应该完全是一次性的。关键是要持久化到数据库或其他一些存储中,因此它们本身不应该包含任何需要持久化的数据。
总而言之,这里最好的办法是简单地将你的 repo(s) 范围限定,这样你就可以直接注入上下文。就构造函数注入而言,我不确定您从哪里得知这是一种不好的做法。这实际上是大多数情况下依赖注入的工作方式,因此您不能真正拥有一个而没有另一个。
如果你绝对需要一个单例,那么你唯一的选择就是服务定位器反模式。为此,您将注入IServiceProvider:
public class MyRepo
{
    private readonly IServiceProvider _serviceProvider;
    public MyRepo(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
    ...
}
然后,每次您需要上下文(这很重要)时,您都需要执行以下操作:
using (var scope = _serviceProvider.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<MyContext>();
    // do something with context
}
| 归档时间: | 
 | 
| 查看次数: | 3007 次 | 
| 最近记录: |