Ninject通用集合的隐式构造函数绑定错误

时间:2014-07-17 21:19:39

标签: c# .net 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 =使用ObservableCollection {IComponent}的隐式自绑定激活ObservableCollection {IComponent}时出错 几个构造函数具有相同的优先级。请使用ToConstructor语法指定构造函数或添加Inject属性。

构造: ObservableCollection 1(List{IComponent} list) [__DynamicallyInvokable]ObservableCollection 1(IEnumerable {IComponent}集合)

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

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

源= Ninject   堆栈跟踪:        在Ninject.Activation.Providers.StandardProvider.Create(IContext context)        在Ninject.Activation.Context.ResolveInternal(对象范围)        在Ninject.Activation.Context.Resolve()        在Ninject.KernelBase。&lt;&gt; c__DisplayClass15.b__f(IBinding绑定)        在System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable 1来源)        在Ninject.Planning.Targets.Target 1.GetValue(Type service, IContext parent) at Ninject.Planning.Targets.Target 1.ResolveWithin(IContext parent)        在Ninject.Activation.Providers.StandardProvider.GetValue(IContext context,ITarget target)        在Ninject.Activation.Providers.StandardProvider。&lt;&gt; c__DisplayClass4.b__2(ITarget目标)        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)        在Ninject.Activation.Providers.StandardProvider.Create(IContext context)        在Ninject.Activation.Context.ResolveInternal(对象范围)        在Ninject.Activation.Context.Resolve()        在Ninject.KernelBase。&lt;&gt; c__DisplayClass15.b__f(IBinding绑定)        在System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.<CastIterator>d__b1 1.MoveNext()        在System.Linq.Enumerable.Single [TSource](IEnumerable`1 source)        在Ninject.ResolutionExtensions.Get [T](IResolutionRoot root,IParameter []参数)        位于C:\ Users \ user.name \ workspace \ vs2010 \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs中的ConsoleApplication2.MyProgram.Main():第36行        在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args)        在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)        在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)        在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)        在System.Threading.ThreadHelper.ThreadStart()   InnerException:

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

1 个答案:

答案 0 :(得分:2)

正如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()绑定,但我不推荐它。另请参阅What's the difference between .ToConstructor and .ToMethod in Ninject 3?

相关问题