在ASP.NET Core中创建作用域工厂

19

我希望在ASP.NET Core中创建作用域容器,并在我的单例方法的2个方法中使用它。

我尝试在单例的每个方法中创建它,它能够工作,但我认为这是冗余的。

var scopeFactory = _serviceProvider.GetService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var scopedContainer = scope.ServiceProvider;

每次需要时,我都在每种方法中都写了它。 我认为这是逻辑错误。 请告诉我如何正确地做?谢谢。


1
从技术角度来看,错误很可能是你的服务本来就是单例的。如果它需要使用作用域服务,那么有一个很强的论点认为它也应该被作用域化。 - Chris Pratt
错误可能在于您有很多需要这种逻辑的方法。只有作为您的组合根一部分的基础设施组件应该需要此项功能,这将导致只有少数(最多)几个地方需要创建新作用域。 - Steven
1个回答

65

从技术上讲,您现在的做法并不是错误的。如果您在单例服务内部需要访问作用域服务,则应该创建一个新的服务作用域,并从该作用域的服务提供程序中检索服务。当您完成后,还应该处理作用域

实际上,您可以简化这个过程。您应该避免直接向服务注入IServiceProvider。相反,您可以直接注入IServiceScopeFactory。然后您还应该使用using语句创建范围,以确保使用后将其正确处理。

因此,一个示例单例服务可能如下所示:

public class ExampleSingletonService
{
    private readonly IServiceScopeFactory _serviceScopeFactory;

    public ExampleSingletonService(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
    }

    public async Task DoSomethingAsync()
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var db = scope.ServiceProvider.GetService<MyDbContext>();

            db.Add(new Foo());
            await db.SaveChangesAsync();
        }
    }
}

正如您所看到的,这并没有太多的开销。但是,当然这让你需要仔细考虑是否想要在单例中使用作用域服务。


谢谢您,我已经看了很多答案,但这个解释得非常清楚! - Chris Owens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接