c# - 无法使 Autofac 嵌套范围工作(嵌套的多个工作单元应该有一个新的 dbcontext )

标签 c# dependency-injection autofac unit-of-work mediatr

我正在尝试使用 Autofac 和 Mediatr 实现工作单元。 这里流程如何

architecture

但我无法让 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/

相关文章:

string - 无法在类型 'System.String' 上具有相同长度 1 的多个构造函数之间进行选择

c# - 更改用户控件上的光标

c# - 我应该使用什么来临时存储将被重用的 XML 数据?

c# - 快速找到该对象的方法已更新

asp.net-mvc - Unity 不解析依赖

c# - Autofac 的混合生活方式

autofac - 理解 Autofac 中 Lifetime 范围的概念

c# - 使用对象哈希的字典

java - Spring Beans 中的构造函数参数太多

javascript - Angular 依赖性