c# - Ninject 泛型集合的隐式构造函数绑定(bind)错误

标签 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} 的隐式自绑定(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/

相关文章:

c# - 在 C# 中的有限线程池上使用来自多个套接字的 IO 完成端口

c# - 使用 .net 组合框

c# - Ninject 内核绑定(bind)覆盖

c# - Google Plus API 获取相册/视频

c# - 嵌套两个 lambda 风格的 Func 表达式

c# - 在非 MVC 应用程序中注入(inject)

.net - Ninject:如何根据依赖链设置绑定(bind)

c# - WinForms:寻找一种简单的方法来弹出 'Processing..' 面板

C# 打开 DBF 文件

c# - 使用 ConfigurationManager 的 OpenExeConfiguration 和 GetSection,(自定义配置文件和部分)