考虑以下代码:
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} 的隐式自绑定(bind)激活 ObservableCollection{IComponent} 时出错 多个构造函数具有相同的优先级。请使用 ToConstructor 语法指定构造函数或添加 Inject 属性。
构造函数:
可观察集合 1(List{IComponent} list)
[__DynamicallyInvokable]ObservableCollection
1(IEnumerable{IComponent}集合)
激活路径: 2)将依赖项 ObservableCollection{IComponent} 注入(inject)到 Aggregator 类型的构造函数的参数 componentList 中 1) 请求聚合器
建议: 1) 确保实现类型具有公共(public)构造函数。 2) 如果您已经实现了 Singleton 模式,请改用 InSingletonScope() 的绑定(bind)。
来源=Ninject
堆栈跟踪:
在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.<>c__DisplayClass15.b__f(IBinding 绑定(bind))
在 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父级)
在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标)
在 Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.b__2(ITarget 目标)
在 System.Linq.Enumerable.WhereSelectArrayIterator 2.MoveNext()
at System.Linq.Buffer
1..ctor(IEnumerable 1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 个源)
在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.<>c__DisplayClass15.b__f(IBinding 绑定(bind))
在 System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1
1.MoveNext()
在 System.Linq.Enumerable.Single[TSource](IEnumerable`1 源)
在 Ninject.ResolutionExtensions.Get[T](IResolutionRoot 根,IParameter[] 参数)
在 C:\Users\user.name\workspace\vs2010\ConsoleApplication2\ConsoleApplication2\Program.cs 中的 ConsoleApplication2.MyProgram.Main() 处:第 36 行
在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,String[] args)
在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,字符串 [] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.RunInternal(ExecutionContextexecutionContext,ContextCallback回调,对象状态, bool 保留SyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback 回调,对象状态, bool 保留SyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback 回调,对象状态)
在 System.Threading.ThreadHelper.ThreadStart()
内部异常:
该错误是由 ObservableCollection 隐式构造函数绑定(bind)引起的。有人可以提供有关如何解决此问题的任何想法或指示吗?
最佳答案
正如 ninject 所说,它不知道如何构造 ObservableCollection<>
因为它有两个具有相同参数计数的可公开访问的构造函数。
当有多个构造函数时,ninject 会检查哪个构造函数可以解析最多的参数,然后选择该构造函数。 有
-
ObservableCollection<T>(IEnumerable<T>)
-
ObservableCollection<T>(List<T>)
这两个 ninject 都可以使用(只要您为 T
定义了绑定(bind))。
现在,覆盖该行为的最简单方法是放置 [Inject]
您希望 ninject 使用的 ctor 上的属性。由于ObservableCollection<>
的源代码不在你的控制之下,你做不到。
您可以做的是指定 ObservableCollection<>
的绑定(bind)它告诉 Ninject 如何创建它。您可以使用 .ToConstructor()
来执行此操作语法(如异常(exception)所述):
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?
关于c# - Ninject 泛型集合的隐式构造函数绑定(bind)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24813728/