【问题标题】:Ninject Implicit constructor binding error for generic collectionsNinject 泛型集合的隐式构造函数绑定错误
【发布时间】:2014-07-17 21:19:38
【问题描述】:

考虑以下代码:

using System.Collections.ObjectModel;
using Ninject;

namespace ConsoleApplication2 {

  public interface IComponent {
    //stuff
  }

  public class Component : IComponent {
    // implementation of stuff
  }

  public class Aggregator {
    private ObservableCollection<IComponent> _componentList;

    public Aggregator(ObservableCollection<IComponent> componentList) {
        _componentList = componentList;
    }

    public ObservableCollection<IComponent> ComponentList { get { return _componentList; }   }
  }

  public class Bindings : Ninject.Modules.NinjectModule {

    public override void Load() {
        Bind<IComponent>().To<Component>();
    }
  }

  public class MyProgram {

    public static void Main() {
        Ninject.IKernel kernel = new StandardKernel(new Bindings());
        var myAgg = kernel.Get<Aggregator>();
    }
  }
}

对我来说,这失败了,运行时异常:

Ninject.ActivationException 未处理 H结果=-2146233088 消息=使用 ObservableCollection{IComponent} 的隐式自绑定激活 ObservableCollection{IComponent} 时出错 多个构造函数具有相同的优先级。请使用 ToConstructor 语法指定构造函数或添加 Inject 属性。

构造函数: ObservableCollection1(List{IComponent} list) [__DynamicallyInvokable]ObservableCollection1(IEnumerable{IComponent} 集合)

激活路径: 2) 将依赖 ObservableCollection{IComponent} 注入到 Aggregator 类型的构造函数的参数 componentList 中 1) 请求聚合器

建议: 1) 确保实现类型具有公共构造函数。 2) 如果你已经实现了 Singleton 模式,请改用 InSingletonScope() 的绑定。

来源=Ninject 堆栈跟踪: 在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.c__DisplayClass15.b__f(IBinding 绑定) 在 System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 源) 在 Ninject.Planning.Targets.Target1.GetValue(Type service, IContext parent) at Ninject.Planning.Targets.Target1.ResolveWithin(IContext parent) 在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标) 在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass4.b__2(ITarget 目标) 在 System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 源) 在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.c__DisplayClass15.b__f(IBinding 绑定) 在 System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.<CastIterator>d__b11.MoveNext() 在 System.Linq.Enumerable.Single[TSource](IEnumerable`1 源) 在 Ninject.ResolutionExtensions.Get[T](IResolutionRoot 根,IParameter[] 参数) 在 C:\Users\user.name\workspace\vs2010\ConsoleApplication2\ConsoleApplication2\Program.cs:line 36 中的 ConsoleApplication2.MyProgram.Main() 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 内部异常:

错误是由 ObservableCollection 隐式构造函数绑定引起的。有人可以提供有关如何解决此问题的任何想法或指示吗?

【问题讨论】:

    标签: c# .net ninject


    【解决方案1】:

    正如 ninject 所说,它不知道如何构造 ObservableCollection&lt;&gt;,因为它有两个具有相同参数计数的可公开访问的构造函数。

    当有多个构造函数时,ninject 检查它可以解析最多的参数,并选择这个构造函数。 有

    • ObservableCollection&lt;T&gt;(IEnumerable&lt;T&gt;)
    • ObservableCollection&lt;T&gt;(List&lt;T&gt;)

    ninject 都可以使用(只要您定义了T 的绑定)。

    现在,覆盖该行为的最简单方法是在您希望 ninject 使用的 ctor 上放置一个 [Inject] 属性。由于ObservableCollection&lt;&gt;的源代码不在你的控制之下,你不能这样做。 你可以做的是为 ObservableCollection&lt;&gt; 指定一个绑定,它告诉 Ninject 如何创建它。您可以使用.ToConstructor() 语法来执行此操作(如例外所述):

    kernel
      .Bind<ObservableCollection<IComponent>>()
      .ToConstructor(x => 
         new ObservableCollection<IComponent>(x.Inject<IList<IComponent>>()));
    

    理论上您也可以使用.ToMethod() 绑定,但我不推荐它。另见What's the difference between .ToConstructor and .ToMethod in Ninject 3?

    【讨论】:

    • 谢谢你,成功了。这是我使用 ninject 的第一天,所以我是新手。
    • 不客气。学习新事物是一件很棒的事情,即使一个人必须从头开始。您会看到 ninject 的异常消息非常有用(尽管并不完美)。
    猜你喜欢
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 2013-09-28
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多