2016-01-13 30 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) –