2014-07-15 25 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(); 

這將阻止您必須更新生存期範圍才能傳遞上下文參數。