项目嵌入式IoC容器

时间:2012-01-23 08:17:51

标签: .net inversion-of-control mef ioc-container

我正在寻找一个非常简单轻巧的IoC容器,其C#源可以包含在我自己的项目中(因此不会进行外部引用)。

这样做的原因是我正在编写基础结构,并希望提供单个.dll文件,而不需要任何其他依赖项。

我也不想使用IoC程序集ILMerge我的程序集。

我想过MEF,其他一些建议?

4 个答案:

答案 0 :(得分:3)

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

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

同时查看this问题,该问题有一些好的答案。 TinyIoC看起来只是一个源文件。

答案 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是一个可以做到这一点的工具,大多数商业混淆器也可以帮助你做到这一点。如果您正在构建商业图书馆或应用程序,我肯定会建议您使用合适的混淆器。