Autofac - 组件忽略生命周期范围中定义的依赖关系

时间:2014-07-15 15:43:46

标签: c# autofac lifetime-scoping

我很可能在这里误解了一些东西,所以也许这里有一个简单的答案,但我现在正在摸不着头脑。

我有一个实现IUnitOfWork的UnitOfWork类(是的,我知道)。工作单元的构造函数采用IPrincipalFactory。 TResponder是图表的顶层,它采用了IUnitOfWork。

我正在尝试将ApplicationPrincipalFactory注册为生命周期范围内的特定实例...它依赖于传递给HandleAsync函数的一些属性。我正在做以下事情:

    public async Task<TResponse> HandleAsync<TMessage, TResponse, TResponder>(TMessage message)
        where TMessage : class
        where TResponder : IRespondAsync<TMessage, TResponse>
    {
        using (var scope = this.BeginLifetimeScope(message))
        {
            var responder = scope.Resolve<TResponder>();
            return await responder.Respond(message);
        }
    }

    private ILifetimeScope BeginLifetimeScope<TMessage>(TMessage message)
    {
        var unwrapped = GetDomainContext(message);
        var applicationPrincipalFactory = this.CreateApplicationPrincipalFactory(unwrapped);

        var lifetime = this.container.BeginLifetimeScope(
            r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());

        return lifetime;
    }

    private ApplicationPrincipalFactory CreateApplicationPrincipalFactory(IDomainContext unwrapped)
    {
        var applicationPrincipalFactory =
            new ApplicationPrincipalFactory(
                unwrapped.Tenant,
                unwrapped.ActingTenant,
                unwrapped.Username);

        return applicationPrincipalFactory;
    }

根据我读过的所有内容,在BeginLifetimeScope中定义依赖关系(r =&gt;应该覆盖父容器绑定,所以当我调用resolve时,它应该整齐地插在一起。

然而,我得到一个例外:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Platform.Engine.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Platform.Engine.Security.IPrincipalFactory principalFactory' of constructor

我没有在此方法之外的任何地方注册IPrincipalFactory。 IUnitOfWork在外部作用域中定义如下:

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();

我还尝试在子容器中重新定义unitofwork注册,以防它出现问题,因为它在外部容器中注册而不是生命周期容器:

        var lifetime = this.container.BeginLifetimeScope(
            r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());

        var overrides = new ContainerBuilder();
        overrides.RegisterType<UnitOfWork>().As<IUnitOfWork>();
        overrides.Update(lifetime.ComponentRegistry);

        return lifetime;

我不确定我缺少什么......有什么想法或建议吗?

1 个答案:

答案 0 :(得分:0)

在初始容器配置期间,将工厂注册到其他类型。

builder.RegisterType<ApplicationPrincipalFactory>().As<IPrincipalFactory>();

然后在您的生命周期范围内解析您可以将上下文传递到的委托工厂。

var factory = container.Resolve<Func<IDomainContext, IPrincipalFactory>>();
var instance = factory(context);

您还可以向string签名添加三个Func<>参数,但由于您已经有了一个很好的上下文对象,我只会将其传递给它。

最后,根据需要使用工厂。

instance.DoesSomethingButNotSureWhat();

这将阻止您只需传递上下文参数来更新生命周期范围。