注入实现使用Ninject相同的接口不同类别 [英] Inject different classes that implement the same interface using Ninject

查看:128
本文介绍了注入实现使用Ninject相同的接口不同类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我采取了建设者的设计模式,构建不同类型的图形对象,将被显示在一个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));
    }
}

根据加里您的评论,你(奇怪的是)跌进相似,我问了一个问题,约了几个小时前的领土。在这里看到雷莫的回答是:使用WithConstructorArgument和创建bound类型

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相同的接口不同类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆