如何使用带有参数的 autofac 寄存器 - Lambda 表达式类型

本文关键字:寄存器 Lambda 表达式 类型 autofac 何使用 参数 | 更新日期: 2023-09-27 18:30:16

>Autofac 文档

阅读了文档并认为要使用参数注册一个类型,我必须以这种方式进行调用:

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

从示例中,我认为这将注册组件,并期望有一个名为 currentServiceGroupId 的 int 参数

但它似乎不是那样工作的

我得到"序列不包含任何元素",因为autofac正在调用IEnumerable.First并试图在列表中找到该元素。我想 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))));
}
}

如何使用带有参数的 autofac 寄存器 - Lambda 表达式类型

Named 扩展方法允许您从 Parameter 的集合中检索特定参数。在您的情况下,您想要创建一个新参数,要创建新参数,您可以创建一个新的实例NamedParameter

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

在这种情况下,您不必使用 lambda Register 方法,您可以使用 WithParameters 方法:

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