我正在尝试使用 Autofac 和 Mediatr 实现工作单元。 这里流程如何
但我无法让 Autofac 在范围内发送相同的 Unit OfWork 实例(它以 DbContext 作为参数)。 我想在单个事务中执行整个范围,这意味着什么时候 我到了 processHandler 的地步,它应该创建一个 DbContext 的实例,并且 将同一个实例共享到嵌套处理程序中。这样我就可以在进程处理程序级别创建事务并将同一事务共享给嵌套处理程序。
这是我的 DI 设置
builder.Register(ctx =>
{
var contextSvc = ctx.Resolve<IContextService>(); // owin context
var connBuilder = ctx.Resolve<IDbConnectionBuilder>();
return SapCommandDb.Create(contextSvc.GetMillCode(), connBuilder.BuildConnectionAsync(IntegrationConnectionName, contextSvc.GetMillCode()).Result);
}).AsSelf().InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IDomainRepository<>)).InstancePerLifetimeScope();
builder.RegisterType<EFUnitOfWork>().As<IEFUnitOfWork>().InstancePerLifetimeScope();
public class ProcessHandler : AsyncRequestHandler<IntermediateDocument.Command>
{
IMediator _mediator;
Func<Owned<IEFUnitOfWork>> _uow;
ILifetimeScope _scope;
public ProcessHandler(
ILifetimeScope scope,
Func<Owned<IEFUnitOfWork>> uow,
IMediator mediator)
{
_mediator = mediator;
_scope = scope;
_uow = uow;
}
protected async override Task Handle(Command request, CancellationToken cancellationToken)
{
foreach (var transaction in request.Transactions)
{
using (var scope = _scope.BeginLifetimeScope("custom"))
{
using (var uo = _uow())
{
await uo.Value.Execute(async () =>
{
await _mediator.Send(new NestedHandlerGetBySwitch.Command(transaction));
});
}
}
}
}
}
上面一个是进程handler
public class NestedHandler1 : AsyncRequestHandler<NestedHandler.Command>
{
IMediator _mediator;
IEFUnitOfWork _uow;
public NestedHandler1(
IEFUnitOfWork uow,
IMediator mediator)
{
_mediator = mediator;
_uow = uow;
}
protected async override Task Handle(Command request, CancellationToken cancellationToken)
{
_uow.Repository.Add(request);
}
}
以上是嵌套处理程序的示例。 我想要来自 processhandler 的相同 _uow 实例。
EFUNitOFWork 看起来像
public class EfUnitOfWork : IEFUnitOfWork {
private DbContext _context;
ABCRepository aBCRepository;
public ABCRepository ABCRepository { get {
return aBCRepository = aBCRepository ?? new ABCRepository(_context);
} }
public EfUnitOfWork(DbContext context)
{
_context = context;
}
public Task Add(Entity entity) {
await _context.AddAsync(entity);
}
}
我做错了什么?
谢谢。
最佳答案
IMediator
要求 AutoFac 创建 NestedHandler1
的实例, 因此它将具有与 IMediator
相同的生命周期范围.
解决它的一种方法是解决 IMediator
来自“自定义”生命周期范围并使用它而不是将其注入(inject)构造函数,并确保 UnitOfWork 已在此范围内正确注册:
using (var uo = _uow())
{
using (var scope = _scope.BeginLifetimeScope("custom", x => x.RegisterInstance(uo.Value))
{
var mediator = scope.Resolve<IMediator>();
await uo.Value.Execute(async () =>
{
await mediator.Send(new NestedHandlerGetBySwitch.Command(transaction));
});
}
}
关于c# - 无法使 Autofac 嵌套范围工作(嵌套的多个工作单元应该有一个新的 dbcontext ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52371942/