当完全注入(inject)特定类型(通过命名约定)时,我需要将 ICommand 绑定(bind)到特定实现,然后我还需要一个具有 IEnumerable<ICommand> 构造函数参数的类型的多重绑定(bind) - 并且需要接收相同的实例,因为我需要我的命令 InSingletonScope。

我试过这个,除此之外:

// note: ICommandMenuItem naming convention for [Foo]Command: [Foo]CommandMenuItem
var item = types.SingleOrDefault(type => type.Name == commandName + "CommandMenuItem");
if (item != null)
{
    _kernel.Bind<ICommand>().To(command)
           .WhenInjectedExactlyInto(item)
           .InSingletonScope()
           .DefinesNamedScope("commands");

    _kernel.Bind<ICommand>().To(command)
           .WhenInjectedExactlyInto<ConfigurationLoader>()
           .InNamedScope("commands");
}

但是每次我进入 ConfigurationLoader 的构造函数时, IEnumerable<ICommand> 参数都不包含任何元素。有或没有命名范围都一样,我想我需要告诉 Ninject “看,我有这两个相同类型的绑定(bind),我希望你给我两个相同的实例”。

第一个绑定(bind)有效 - 我知道是因为我的菜单项在被点击时会做一些事情。但是 ICommand 被(不是?!)注入(inject) ConfigurationLoader 的方式有问题,我不知道如何修复它。

最佳答案

据我所知,命名范围在这里没有意义:

  • DefinesNamedScope 定义命名范围
  • 的根
  • InNamedScope 确保根的依赖树中只有一个 T 实例。这也意味着一旦根对象被垃圾收集,它就会被处理。

  • 当您希望所有命令都在单例范围内时,请不要使用其他命令。此外,只要 ConfigurationLoader 不是菜单项的( transient )依赖项,无论如何都不会满足 InNamedScope

    此外,每个绑定(bind)都应用 InSingletonScope()。 IE。如果同一类型有两个绑定(bind),InSingletonScope() 将(可能)产生两个实例。这就是为什么有 Bind(Type[]) 重载的原因,您可以在其中将多个服务绑定(bind)到一个分辨率。

    您需要的是具有 OR 条件的单个绑定(bind):
    // note: ICommandMenuItem naming convention for [Foo]Command: [Foo]CommandMenuItem
    var item = types.SingleOrDefault(type => type.Name == commandName + "CommandMenuItem");
    if (item != null)
    {
        _kernel.Bind<ICommand>().To(command)
               .WhenInjectedExactlyIntoAnyOf(item, typeof(ConfigurationLoader))
               .InSingletonScope();
    }
    

    当然,现在 WhenInjectedExactlyIntoAnyOf 不可用。另外,遗憾的是,ninject 没有以开箱即用的方式来结合现有条件。因此,您必须根据 When(Func<IRequest,bool> condition) 推出自己的条件。

    有一种结合现有 When... 条件的稍微有点hackish 的方法。
    可以先创建绑定(bind),没有任何条件,然后添加一个条件,检索它(它是一个 Func<IRequest,bool> ),然后替换条件,检索它,组合它,替换它......等等......
    // example binding without condition
    var binding = kernel.Bind<string>().ToSelf();
    
    // adding an initial condition and retrieving it
    Func<IRequest, bool> whenIntegerCondition = binding.WhenInjectedInto<int()
        .BindingConfiguration.Condition;
    
    // replacing condition by second condition and retrieving it
    Func<IRequest, bool> whenDoubleCondition = binding.WhenInjectedInto<double>().
        BindingConfiguration.Condition;
    
    // replacing the condition with combined condition and finishing binding
    binding.When(req => whenIntCondition(req) || whenDoubleCondition(req))
           .InSingletonScope();
    

    关于c# - 注入(inject) InSingletonScope 的对象是否也可以注入(inject)其他地方的多绑定(bind)中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36276535/

    10-12 22:20
    查看更多