Mat*_*don 3 c# dependency-injection ninject
我需要在完全注入特定类型(通过命名约定)时绑定ICommand
到特定实现,然后我还需要一个具有构造函数参数的类型的多重绑定- 并且需要接收相同的实例,因为我需要我的命令InSingletonScope.IEnumerable<ICommand>
我试过这个,其中包括:
// 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");
}
Run Code Online (Sandbox Code Playgroud)
但每次我进入构造函数时ConfigurationLoader
,IEnumerable<ICommand>
参数都不包含任何元素.无论是否有命名范围,我认为我需要告诉Ninject"看起来我有两个相同类型的绑定,我希望你给我两个相同的实例".
第一个绑定工作 - 我知道因为我的菜单项在点击时会做一些事情.但是ICommand
注入(不是?!)的方式有问题ConfigurationLoader
,我不知道如何修复它.
据我所知,命名范围在这里没有意义:
DefinesNamedScope
定义命名范围的根InNamedScope
确保T
根目录的依赖树中只有一个实例.这也意味着一旦根对象被垃圾收集,它就会被处理掉.如果希望所有命令都在Singleton范围内,则不要使用其他命令.此外,只要ConfigurationLoader
不是菜单项的(瞬态)依赖性InNamedScope
,无论如何都不会满足.
此外,InSingletonScope()
每个绑定应用.即如果你有两个相同类型的绑定,InSingletonScope()
将(可能)导致两个实例.这就是为什么有Bind(Type[])
重载,你可以将多个服务绑定到一个分辨率.
您需要具备的是具有OR
条件的单个绑定:
// 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();
}
Run Code Online (Sandbox Code Playgroud)
当然,现在WhenInjectedExactlyIntoAnyOf
还没有.另外,令人遗憾的是,ninject并没有采用开箱即用的方式来结合现有条件.所以,你必须根据自己的条件When(Func<IRequest,bool> condition)
.
结合现有When...
条件有一种轻微的hackish方式.可以先创建绑定,没有任何条件,然后添加条件,检索它(它是a 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();
Run Code Online (Sandbox Code Playgroud)