我正在将我的项目从经典的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();
现在,在新项目中,我使用的是在控制器操作中调用的托管服务。因此,我创建了一个BackgroundQueue
和QueuedService
实现,并像这样注册:
builder.RegisterType<BackgroundQueue>()
.As<IBackgroundQueue>()
.SingleInstance();
builder.RegisterType<QueuedService>()
.As<IHostedService>()
.InstancePerDependency();
控制器操作可能使用一项特定服务。在这种情况下,生存期范围就足够了,因为在请求结束时会丢弃实例。现在,特定的控制器动作将产生一个新的排队服务,例如:
backgroundQueue.QueueBackgroundWorkItem(async ct => { //Do stuff... });
该任务可能需要使用相同特定服务的实例。在这种情况下,任务需要创建一个全新的实例,因为任务将在请求结束后继续保持运行状态。
因此,如果我将UoW注册并且我所有的服务始终都注册为InstancePerDependency
,这应该满足两种情况吗?
如果后台作业使用其他服务,例如注册为DbContext
的InstancePerLifetimeScope
,则可能需要将子作用域与为该作业范围注册的服务一起使用:
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...
}
});
}
}