Ninject 泛型集合的隐式构造函数绑定错误



请考虑以下代码:

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 未处理 HResult=-2146233088 Message=Error 激活 ObservableCollection{IComponent} using ObservableCollection{IComponent} 的隐式自绑定多个构造函数具有相同的优先级。请使用 ToConstructor 语法指定构造函数或添加 Inject 属性。

构造 函数:ObservableCollection 1(List{IComponent} list) [__DynamicallyInvokable]ObservableCollection 1(IEnumerable{IComponent} collection(

激活路径: 2( 将依赖关系 ObservableCollection{IComponent} 注入到参数组件聚合器类型的构造函数列表中 1( 请求聚合器

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

来源=Ninject 堆栈跟踪: at Ninject.Activation.Providers.StandardProvider.Create(IContext context( at Ninject.Activation.Context.ResolveInternal(Object scope( at Ninject.Activation.Context.Resolve(( at Ninject.KernelBase.<>c__DisplayClass15.b__f(IBinding binding( at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable 1 source( at Ninject.Planning.Targets.Target 1.GetValue(Type service, IContext parent) at Ninject.Planning.Targets.Target 1.ResolveWithin(IContext parent( at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target( at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.b__2(ITarget target( at System.Linq.Enumerable.WhereSelectArrayIterator 2.MoveNext() at System.Linq.Buffer 1..ctor(IEnumerable 1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable 1 source( at Ninject.Activation.Providers.StandardProvider.Create(IContext context( at Ninject.Activation.Context.ResolveInternal(Object scope( at Ninject.Activation.Context.Resolve(( at Ninject.KernelBase.<>c__DisplayClass15.b__f(IBinding binding( at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.<CastIterator>d__b1 1.MoveNext(( at System.Linq.Enumerable.Single[TSource](IEnumerable'1 source( at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters( at ConsoleApplication2.MyProgram.Main(( in C:\Users\user.name\workspace\vs2010\ConsoleApplication2\ConsoleApplication2\Program.cs:line 36 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args( at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args( at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly(( 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态( at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx( at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx( at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state( at System.Threading.ThreadHelper.ThreadStart(( 内部异常:

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

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

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

  • ObservableCollection<T>(IEnumerable<T>)
  • ObservableCollection<T>(List<T>)

Ninject 都可以使用这两种方法(只要您为 T 定义了绑定(。

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

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

理论上你也可以使用 .ToMethod() 绑定,但我不推荐它。另请参阅两者之间有什么区别。ToConstructor 和 .Ninject 3中的To方法?

最新更新