我最近一直在研究依赖注入和控制反转实践,以改进我们的应用程序框架的体系结构,我似乎无法找到这个问题的好答案。很可能我的术语混乱,混乱,或者我现在对这个概念很幼稚,所以任何链接或澄清都会受到赞赏。
DI和IoC容器的许多示例没有说明当您拥有可能的“插件”“库”或如何“序列化”给定配置时容器如何将事物连接在一起。 (从我读过的关于MEF的内容来看,如果你的对象只需要1 [导入],那么对同一类型的[导出]的多个声明将不起作用。也许这是一种不同的模式,或者我被当前的思维模式所蒙蔽。
以下是一些示例参考的代码:
public abstract class Engine {
}
public class FastEngine : Engine {
}
public class MediumEngine : Engine {
}
public class SlowEngine : Engine {
}
public class Car
{
public Car(Engine e)
{
engine = e;
}
private Engine engine;
}
这篇文章谈到了“细粒度上下文”,其中同一对象的2个实例需要不同的“引擎”类实现:IoC.Resolve vs Constructor Injection
是否有一个好的框架可以帮助您配置或序列化配置以实现类似的功能而无需对其进行硬编码或手动编写代码来执行此操作?
public class Application
{
public void Go()
{
Car c1 = new Car(new FastEngine());
Car c2 = new Car(new SlowEngine());
}
}
示例XML:
<XML>
<Cars>
<Car name="c1" engine="FastEngine" />
<Car name="c2" engine="SlowEngine" />
</Cars>
</XML>
答案 0 :(得分:1)
我不了解mef,但是Spring使用您描述的几乎完全相同的方法(由XML文件或配置部分配置注入)完全按照您的描述进行:
<objects>
<object name="FastCar" type="MyApp.Car">
<constructor-arg>
<ref object="FastEngine">
</constructor-arg>
</object>
<object name="SlowCar" type="MyApp.Car">
<constructor-arg>
<ref object="SlowEngine">
</constructor-arg>
</object>
<object name="FastEngine" type="MyApp.FastEngine"/>
<object name="SlowEngine" type="MyApp.SlowEngine"/>
</objects>
答案 1 :(得分:0)
使用MEF(您提到过),您可以使用[ImportMany]
导入Engine实例的集合。然后,您可以为每个引擎创建一个汽车,并返回该汽车,无需XML。
public class Application
{
[ImportMany]
public IEnumerable<Engine> Engines { get; set; }
public void Go()
{
// I'm assuming this object was composed already...
var cars = this.Engines.Select(e => new Car(e));
foreach(var car in cars)
{
// Do something with each car
}
}
}
这样做的好处是可以随时添加新的“引擎”,而无需更改代码。所有接线都在运行时动态处理,无需配置。
答案 2 :(得分:0)
大多数DI容器都支持 XML配置 - 事实上,大多数DI容器都是以这种方式开始的,而XML配置只是 选项。如今,XML configuration is one option among several。
但是,在目前的版本中,MEF不使用XML配置。它也不是DI容器。