【问题标题】:Project-Embedded IoC Container项目嵌入式 IoC 容器
【发布时间】:2012-02-16 15:08:46
【问题描述】:

我正在寻找一个非常简单和轻量级的 IoC 容器它的 C# 源代码可以包含在我自己的项目中(因此不做外部参考)。

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

我也不想 ILMerge 我的程序集与 IoC 程序集..

我考虑过 MEF,还有其他建议吗?

【问题讨论】:

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


【解决方案1】:

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

【讨论】:

  • Windsor 不是我对轻量级容器的定义。它包括大约 4 个程序集和许多源文件/类。
【解决方案2】:

创建自己的容器并不难,具体取决于您需要的功能类型。但是,这样做很容易造成泄漏,所以我想您可能希望使用经过测试和尝试过的解决方案。

MEF 被一些人用作容器,但(值得注意的)其他人说 MEF is not an IOC container,本质上 MEF 被设计为插件架构而不是依赖注入容器。

考虑到这一切,我建议您将所选容器的完整源代码嵌入到应用程序中,或者使用工具将其程序集合并到您自己的程序集中。 ILMerge 是一个可以做到这一点的工具,大多数商业混淆器也可以帮助你做到这一点。如果您正在构建商业库或应用程序,我绝对建议您使用适当的混淆器。

【讨论】:

  • 正如我在问题中所说,我愿意将容器的源代码嵌入到我自己的项目中,但我正在寻找一个经过测试的容器,其文件和类的数量最少。请不要使用 ILMerge。
  • 对容器有什么要求?您需要什么样的生命周期支持?您想要 XML 配置、流畅的配置 API,还是愿意明确地配置每种类型?
  • 我想通过代码配置容器。希望支持单例和瞬态生命周期。
  • 您可能会发现this blog post 很有趣。它展示了一个超轻量级的容器。它只支持短暂的生活方式,但添加对单身人士的支持应该很容易。这就是你的想法吗?
  • 谢谢。我会看看。我还发现了这个:stackoverflow.com/a/2598839/978164,看起来很有趣。
【解决方案3】:

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

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

还可以查看this 问题,其中有一些很好的答案。 TinyIoC 看起来只是一个源文件。

【讨论】:

  • 感谢 TinyIoC。看起来正是我想要的。
【解决方案4】:

如果您不需要任何花哨的东西,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);

但是,对于复杂的对象图,在重构期间维护正确的构造顺序会很快变得复杂。容器没有这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2018-04-27
    • 1970-01-01
    相关资源
    最近更新 更多