Ninject 泛型集合的隐式构造函数绑定错误
本文关键字:构造函数 绑定 错误 泛型 集合 Ninject | 更新日期: 2023-09-27 18:13:37
请考虑以下代码:
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方法?