2016-01-05 15 views
1

當Autofac嘗試通過依賴關係解析程序解析構造函數參數時,是否可以一次列出所有缺失的註冊?或者是要經過一次一個唯一的方法..列出依賴關係解析程序的所有缺少的Autofac註冊DefaultConstructorFinder

拿這個作爲一個例子:

public MyWebApiController(IMyInterface myInterface) 

我知道實現IMyInterface的類MyInterfaceImpl必須要註冊這樣與Autofacs ContainerBuilder:

builder.RegisterType<MyInterfaceImpl>().As<IMyInterface>() 

但是如果MyInterfaceImpl取決於其他10層構造,和他們每個人依賴於福..有沒有辦法讓Autofac經歷還沒有被登記的ContainerBuilder所有的依賴,而不是拋出一個戴佩爾第一次發生nvanceResolutionException?

採取:

public MyInterfaceImpl(IMyInterface2 myInterface2, IMyInterface3 myInterface3, ... etc ...) 

而且每一種都有自己的構造函數需要註冊..

public MyInterface2Impl(IMyInterfaceB myInterfaceB) 

因爲我已經失蹤Autofac註冊,以下異常消息顯示,告訴我我必須註冊接口,即MyInterface2Impl。與 「Autofac.Core.Activators.Reflection.DefaultConstructorFinder」發現 類型的構造函數

無「MyWebApiController」可以與提供的服務和 參數

和細節顯示哪些調用參數它拒絕:

無法解析構造 「太虛.ctor的參數 'IMyInterface2 myInterface2'(IMyInterface2 myIn terface2,IMyInterface3 myInterface3, ...等...)

但對未來5個人失蹤登記我可能什麼都沒有。這是一個煩惱,因爲我必須啓動站點/服務並調用api控制器,在每次修復缺少的註冊後,有時可能會有很多缺少註冊,當設置coctail時。

所以,Autofac能讓我看到所有缺少的註冊信息嗎?

回答

1

有沒有簡單的方法來做你想做的。我檢查代碼,只顯示第一個參數,請參閱ConstructorParameterBinding.cs in github repository

for (int i = 0; i < parameters.Length; ++i) 
{ 
    var pi = parameters[i]; 
    bool foundValue = false; 
    foreach (var param in availableParameters) 
    { 
     Func<object> valueRetriever; 
     if (param.CanSupplyValue(pi, context, out valueRetriever)) 
     { 
      _valueRetrievers[i] = valueRetriever; 
      foundValue = true; 
      break; 
     } 
    } 
    if (!foundValue) 
    { 
     CanInstantiate = false; 
     _firstNonBindableParameter = pi; 
     break; 
    } 

我認爲這是對性能的原因。

順便說一下,您可以使用ResolveOperationBeginning事件來獲得您想要的特定情況。

#if DEBUG 
container.ResolveOperationBeginning += (sender, e) => 
{ 
    IComponentRegistration registration = null; 
    e.ResolveOperation.InstanceLookupBeginning += (sender2, e2) => 
    { 
     registration = e2.InstanceLookup.ComponentRegistration; 
    }; 

    e.ResolveOperation.CurrentOperationEnding += (sender2, e2) => 
    { 
     if (e2.Exception != null) 
     { 
      ConstructorInfo ci = registration.Activator.LimitType 
                 .GetConstructors() 
                 .First(); 

      StringBuilder sb = new StringBuilder(); 
      sb.AppendLine($"Can't instanciate {registration.Activator.LimitType}"); 

      foreach (ParameterInfo pi in ci.GetParameters()) 
      { 
       if (!((ILifetimeScope)sender).IsRegistered(pi.ParameterType)) 
       { 
        sb.AppendLine($"\t{pi.ParameterType} {pi.Name} is not registered"); 
       } 
      } 

      throw new DependencyResolutionException(sb.ToString(), e2.Exception); 
     } 
    }; 
}; 
#endif 

它不會在所有情況下工作,但如果你只使用構造函數注入沒有複雜的綁定它應該是足夠的。

Complete sample here:https://dotnetfiddle.net/om16sI

+0

Perfect thanks!它適用於我們簡單的場景。 – Bogmag