2016-01-13 57 views
0

Autofac documentation如何使用autofac與參數註冊 - lambda表達式樣

我閱讀文檔,並想通註冊參數類型我不得不撥打電話是這樣的:

builder.Register((c, p) => new HealthController(c.Resolve<IServiceGroupFactory>(), p.Named<int>("currentServiceGroupId"))).As<IHealthStateController>(); 

從例如我認爲這將註冊組件,並期望有一個名爲currentServiceGroupId的int參數

但它似乎並不那樣工作

由於autofac正在調用IEnumerable.First並試圖在列表中找到該元素,因此我得到「Sequence contains no elements」。我猜p是空的,因此錯誤。

我不知道爲什麼它試圖找到它,我認爲這句法將創建序列,並把它的參數的IEnumerable集合在

那麼什麼是使這項工作的正確方法?

和結論部分是後來當分辨率發生

堆棧跟蹤:

at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) 
at Autofac.ParameterExtensions.ConstantValue[TParameter,TValue](IEnumerable`1 parameters, Func`2 predicate) 
at Autofac.ParameterExtensions.Named[T](IEnumerable`1 parameters, String name) 
at NPP.ServiceLayer.ServiceHost.IoCCompositionRoot.<>c.<RegisterExplicitly>b__2_0(IComponentContext c, IEnumerable`1 p) in C:\tfs2012\NPP\Dev\NPP\NPP.ServiceLayer.ServiceHost\App_Start\IoCCompositionRoot.cs:line 116 
at Autofac.Builder.RegistrationBuilder.<>c__DisplayClass1`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p) 
at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) 
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) 
at Autofac.Core.Resolving.InstanceLookup.Execute() 

Autofac的定義爲 「名稱」 擴展

public static class ParameterExtensions 
{ 
    /// <summary> 
    /// Retrieve a named parameter value from a <see cref="T:Autofac.NamedParameter"/> instance. 
    /// 
    /// </summary> 
    /// <typeparam name="T">The type to which the returned value will be cast.</typeparam><param name="parameters">The available parameters to choose from.</param><param name="name">The name of the parameter to select.</param> 
    /// <returns> 
    /// The value of the selected parameter. 
    /// </returns> 
    /// <seealso cref="T:Autofac.NamedParameter"/> 
    public static T Named<T>(this IEnumerable<Parameter> parameters, string name) 
    { 
     if (parameters == null) 
     throw new ArgumentNullException("parameters"); 
     Enforce.ArgumentNotNullOrEmpty(name, "name"); 
     return ParameterExtensions.ConstantValue<NamedParameter, T>(parameters, (Func<NamedParameter, bool>) (c => c.Name == name)); 
    } 

private static TValue ConstantValue<TParameter, TValue>(IEnumerable<Parameter> parameters, Func<TParameter, bool> predicate) where TParameter : ConstantParameter 
{ 
    if (parameters == null) 
    throw new ArgumentNullException("parameters"); 
    if (predicate == null) 
    throw new ArgumentNullException("predicate"); 
    return Enumerable.First<TValue>(Enumerable.Cast<TValue>((IEnumerable) Enumerable.Select<TParameter, object>(Enumerable.Where<TParameter>(Enumerable.OfType<TParameter>((IEnumerable) parameters), predicate), (Func<TParameter, object>) (p => p.Value)))); 
} 
} 

回答

0

Named擴展方法允許您檢索來自Parameter的集合的特定參數。 在你的情況,你要創建一個新的參數,創建您可以創建NamedParameter

builder.Register((c, p) => new HealthController(
           c.Resolve<IServiceGroupFactory>(), 
           new NamedParameter("currentServiceGroupId", 0)) 
     .As<IHealthStateController>(); 

一個新的實例。在這種情況下,一個新的參數,你不必使用拉姆達Register方法,你可以使用WithParameters方法:

builder.RegisterType<HealthController>() 
     .As<IHealthStateController>() 
     .WithParameter(new NamedParameter("currentServiceGroupId", 0); 
+0

非常有意義西里爾,只是想知道爲什麼在文件沒有顯示,你在這裏上面說明使用的例子。 您的第二個示例的一個小問題是,在這種情況下應該使用WithParameter(不帶WithParameter {s}),因爲它只是一個參數在 – ambidexterous

+0

中傳遞您可以在此文檔頁上找到更多信息:[將參數傳遞給Register] (http://docs.autofac.org/en/latest/register/parameters.html) –