请考虑以下代码:
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隐式构造函数绑定引起的。有人可以就如何解决这个问题提供任何想法或指示吗?
答案 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?