2014-07-15 24 views
0

我很可能在这里误解了一些东西,所以也许这里有一个简单的答案,但我现在正在挠头。Autofac - 组件忽略在生存期范围内定义的依赖关系

我有一个类UnitOfWork实现IUnitOfWork(是的,我知道)。工作单元的构造函数需要一个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 =>应该重写父容器结合,所以当我打电话决心,就应该所有插槽一起整齐。

但是,我得到一个异常:

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; 

我不是确定我错过了什么想法或建议?

+0

你的'IPrincipalFactory'有'builder.RegisterType'这行吗? – DavidG

+0

我不会...将RegisterInstance(...)。作为不在这里的地方吗? –

+0

不太确定,我没有使用过Autofac,但基于错误消息,我猜不是。我通常只是使用构建器注册每个类型,然后让Autofac处理其余的部分。 – DavidG

回答

0

在初始容器配置期间注册您的工厂和其他类型的工厂。

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

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

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

你也可以添加三个string参数到Func<>签名,但既然你已经有了一个不错的上下文对象,我只想把它传递代替。

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

instance.DoesSomethingButNotSureWhat(); 

这将阻止您必须更新生存期范围才能传递上下文参数。