Autofac と Mediatr を使用して Unit of Work を実装しようとしています。ここまでの流れは
しかし、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));
});
}
}
}
}
}
上記のものはプロセスハンドラです
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);
}
}
私は何を間違っていますか?
ありがとうございました。