问题描述
我采取了建设者的设计模式,构建不同类型的图形对象,将被显示在一个WPF UI。我使用Ninject作为我的IOC容器。不过,我想找到一个优雅的可扩展的解决方案。
I am implementing the builder design pattern to construct different kinds of graph objects to be displayed on a WPF UI. I am using Ninject as my IOC container. However, I am trying to find an elegant extendable solution.
我有一个 ChartDirector中
对象,需要一个 IChartBuilder
作为一个依赖。我也有 TemperatureChartBuilder
和 ThresholdChartBuilder
实现 IChartBuilder
。我要注入或者 TemperatureChartBuilder
或者根据 ThresholdChartBuilder
到 ChartDirector中
在被解雇或根据客户呼叫的事件。我已经在代码中说明我下面的问题。
I have a ChartDirector
object that takes a IChartBuilder
as a dependency. I also have TemperatureChartBuilder
and ThresholdChartBuilder
that implement IChartBuilder
. I want to inject either TemperatureChartBuilder
OR ThresholdChartBuilder
to ChartDirector
depending on an event that is fired or depending on a client call. I have illustrated my problem below in code.
// ChartDirector also depends on this
kernel.Bind<IExample>().To<Example>();
// when called in Method X...
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>();
// when called in Method Y...
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder();
// TemperatureChartBuilder is a dependency of ChartDirector, need a way to dynamically
// allocate which binding to use.
var director = kernel.Get<ChartDirector>();
// without Ninject I would do
var director = new ChartDirector(new TemperatureChartBuilder);
// or
var director = new ChartDirector(new ThresholdChartBuilder);
编辑:
再加上加利的回答,并注意到有轻微的编辑ChartDirector中有另一个依赖,我现在想要做这样的事情:
Coupled with Gary's answer, and noting a slight edit that ChartDirector has another dependency, I now want to do something like this:
var director = kernel.Get<ChartDirector>().WithConstructorArgument(kernel.Get<IChartBuilder>("TemperatureChart"));
是这样的可能吗?
Is something like this possible?
推荐答案
如果你只是打算使用的服务的位置,在你的例子,然后命名为绑定做工精细,按Garys答案。
If you're just planning to use service location, as in your examples, then named bindings work fine, as per Garys answer.
有一个更好的方法,但是,使用构造器注入,并使用属性。对于为例,从ninject维基:
A better approach, however, is to use constructor injection, and use attributes. For exampl, from the ninject wiki:
Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");
...
...
class WeakAttack {
readonly IWeapon _weapon;
public([Named("Weak")] IWeapon weakWeapon)
_weapon = weakWeapon;
}
public void Attack(string victim){
Console.WriteLine(_weapon.Hit(victim));
}
}
根据加里您的评论,你(奇怪的是)跌进相似,我问了一个问题,约了几个小时前的领土。在这里看到雷莫的回答是:
Based on your comment to Gary, you're (strangely enough) stumbling into territory similar to what I asked a question about a few hours ago. See Remo's answer here: Using WithConstructorArgument and creating bound type
您将使用情况何时确定何时创建正确的实例。
You would use When condition to define when to create the correct instance.
这篇关于注入实现使用Ninject相同的接口不同类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!