2012-01-23 46 views
6

我要寻找一个非常简单,重量轻IoC容器其C#源可以包含在我自己的项目(因此不会外部参考)。项目 - 嵌入式IOC容器

原因是我正在编写一个基础架构,并希望提供一个.dll文件,而不需要任何额外的依赖关系。

我也不想ILMerge我与IOC大会总成..

我想到了MEF,其他一些建议吗?

+0

您可能想要标记此.net以获取更多建议。 –

+1

看看这个问题:http://stackoverflow.com/questions/2515124/whats-the-simplest-ioc-container-for-c有一个在线的例子 –

+6

如果你正在编写一个库,你不应该完全可以使用DI容器:http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657 –

回答

3

如果您使用的是.NET 4.0,则包含MEF。

对于.NET 2,我曾经使用接口和Reflection写过类似的东西。有很多教程描述了这个过程。即使您可以使用MEF,仍然值得尝试一些反思教程,因为这是MEF如何在其下工作的。

也检查出this问题,它有一些很好的答案。 TinyIoC看起来像它只是一个单一的源文件。

+0

感谢TinyIoC。看起来像我正在寻找的。 – dux2

0

我非常喜欢Castle.Windsor它是开源的,所以你可以在相关的代码文件添加到您的项目

+2

Windsor不是我定义的一个轻量级容器。它包括大约4个程序集和许多源文件/类。 – dux2

0

这不是真的那么难推出自己的容器,这取决于你所需要的功能类型。然而,这样做很容易造成泄漏,所以我想你可能会想要使用经过测试和尝试的解决方案。

MEF被某些人用作容器,但其他人则说MEF is not an IOC container,实质上MEF被设计成插件架构而不是依赖注入容器。

考虑到这一切,我会建议您在应用程序中嵌入您选择的容器的完整源代码,或使用工具将它的程序集合并到您自己的程序集中。 ILMerge是一个可以做到的工具,大多数商业混淆器都可以帮助你做到这一点。如果您正在构建商业图书馆或应用程序,我肯定会推荐使用适当的混淆器。

+0

正如我在我的问题中所述,我愿意将容器的源代码嵌入到我自己的项目中,但我正在寻找具有最少数量的文件和类的测试容器。请不要ILMerge。 – dux2

+0

容器的要求是什么?你需要什么样的生命周期支持?你需要XML配置,流畅的配置API还是你很乐意明确配置每种类型? –

+0

我想通过代码配置容器。希望支持单身和瞬态生命周期。 – dux2

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); 

但是,对于复杂的对象图,它可以快速得到compli在重构期间保持正确的施工顺序。容器没有这个问题。