我正在寻找一个非常简单轻巧的IoC容器,其C#源可以包含在我自己的项目中(因此不会进行外部引用)。
这样做的原因是我正在编写基础结构,并希望提供单个.dll文件,而不需要任何其他依赖项。
我也不想使用IoC程序集ILMerge我的程序集。
我想过MEF,其他一些建议?
答案 0 :(得分:3)
如果您使用的是.NET 4.0,则包含MEF。
对于.NET 2,我曾经使用接口和Reflection编写类似的东西。有很多教程描述了这个过程。即使你可以使用MEF,它仍然值得尝试一些反思教程,因为这是MEF在其下工作的方式。
答案 1 :(得分:3)
如果您不需要任何花哨的东西,DI容器可能非常简短:
public class Container
{
private readonly Dictionary<Type,Func<Container,object>> factories;
private readonly Dictionary<Type,object> cache;
public Container()
{
this.factories = new Dictionary<Type,Func<Container,object>>();
this.cache = new Dictionary<Type,object>();
}
public void Register<TContract>(Func<Container,TContract> factory)
{
// wrap in lambda which returns object instead of TContract
factories[typeof(TContract)] = c => factory(c);
}
public TContract Get<TContract>()
{
var contract = typeof(TContract);
if (!cache.ContainsKey(contract))
{
this.cache[contract] = this.factories[contract](this);
}
return (TContract)this.cache[contract];
}
}
您可以这样使用:
var container = new Container();
container.Register<ICar>(c => new Car(
c.Get<IEngine>(), c.Get<IWheel>()));
container.Register<IWheel>(c => new Wheel());
container.Register<IEngine>(c => new Engine());
var car = container.Get<ICar>();
更简约的是在没有容器的情况下进行依赖注入:
IWheel wheel = new Wheel();
IEngine engine = new Engine();
ICar car = new Car(engine, wheel);
但是,对于复杂的对象图,重构期间维护正确的构造顺序很快就会变得复杂。容器没有这个问题。
答案 2 :(得分:0)
我非常喜欢Castle.Windsor这是开源的,所以你可以将相关的代码文件添加到你的项目中
答案 3 :(得分:0)
根据您需要的功能类型,滚动自己的容器并不是那么困难。但是,这样做很容易造成泄漏,所以我猜你可能想要使用经过测试并尝试过的解决方案。
MEF被一些人用作容器,但(值得注意)其他人说MEF is not an IOC container,实质上MEF被设计为插件架构而不是依赖注入容器。
考虑到这一切,我建议你在你的应用程序中嵌入你选择的容器的完整源代码,或者使用工具将它的程序集合成你自己的程序集。 ILMerge是一个可以做到这一点的工具,大多数商业混淆器也可以帮助你做到这一点。如果您正在构建商业图书馆或应用程序,我肯定会建议您使用合适的混淆器。