注册控制器和托管服务时使用InstancePerLifetimeScope或InstancePerDependency?

问题描述 投票:0回答:1

我正在将我的项目从经典的ASP.Net升级到Asp.Net Core 3.1。在以前的项目中,我曾经注册过这样的UoW和服务:

builder.Register(x => new UnitOfWork())
    .As(typeof(IUnitOfWork))
    .InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
    .Where(t => t.Name.EndsWith("Service"))
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

现在,在新项目中,我使用的是在控制器操作中调用的托管服务。因此,我创建了一个BackgroundQueueQueuedService实现,并像这样注册:

builder.RegisterType<BackgroundQueue>()
    .As<IBackgroundQueue>()
    .SingleInstance();

builder.RegisterType<QueuedService>()
    .As<IHostedService>()
    .InstancePerDependency();

控制器操作可能使用一项特定服务。在这种情况下,生存期范围就足够了,因为在请求结束时会丢弃实例。现在,特定的控制器动作将产生一个新的排队服务,例如:

backgroundQueue.QueueBackgroundWorkItem(async ct => { //Do stuff... });  

该任务可能需要使用相同特定服务的实例。在这种情况下,任务需要创建一个全新的实例,因为任务将在请求结束后继续保持运行状态。

因此,如果我将UoW注册并且我所有的服务始终都注册为InstancePerDependency,这应该满足两种情况吗?

c# asp.net-core autofac
1个回答
0
投票

如果后台作业使用其他服务,例如注册为DbContextInstancePerLifetimeScope,则可能需要将子作用域与为该作业范围注册的服务一起使用:

public class MyController
{
    public MyController(ILifetimeScope parentScope)
    {
        var scope = parentScope.BeginLifetimeScope(builder =>
        {
            builder.RegisterType<MyDbContext>()
                .WithParameters(new[] { new TypedParameter(typeof(DbContextOptions), MasterDbContext.GetOptions(masterDbConnectionString)) })
                .InstancePerLifetimeScope()
                .AsSelf();
            [..other services]
        });

        backgroundQueue.QueueBackgroundWorkItem(async ct => 
        { 
            using(scope)
            {
                //Do stuff...
            } 
        }); 
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.