【问题标题】:Is having a wrapper for your IoC a good idea?为您的 IoC 提供包装器是个好主意吗?
【发布时间】:2011-05-14 22:04:40
【问题描述】:

我已经使用 StructureMap 一年多了。一直以来,我都有一个名为 IoC 的包装类,它看起来像这样

class IoC {
    public static T GetInstance<T>()
    {
        return (T)GetInstance(typeof(T));
    }
    public static IEnumerable<T> GetAllInstances<T>()
    {
        return ObjectFactory.GetAllInstances<T>();
    }

    public static IEnumerable GetAllInstances(Type type)
    {
        return ObjectFactory.GetAllInstances(type);
    }

    public static object GetInstance(Type type)
    {
        return ObjectFactory.GetInstance(type);
    }

    public static void Inject<T>(T obj)
    {
        ObjectFactory.Inject(obj);
    }
}

我添加了包装器,假设我可能想在某个时间点更改 IoC 容器。在这一点上,我认为这很糟糕。一个原因是:我不能在我的代码中使用 ObjectFactory 来做其他有趣的事情,我必须使用这个包装器。另一件事是:我们的代码实际上不应该独立于 DependencyInjection 容器。

使用这种方法的优点/缺点是什么?

【问题讨论】:

标签: dependency-injection structuremap ioc-container wrapper abstraction


【解决方案1】:

为此,开发了Common Service Locator 项目。它是对 DI 框架的抽象,它定义了一个与您的 IoC 类非常相似的接口。我什至开发了Simple Service Locator 库;一个直接实现 Common Service Locator 接口的 DI 库。

所以从这个意义上说,对 DI 框架进行抽象并不奇怪。但是,当正确(并且完全)进行依赖注入时,想法是相应地调整应用程序的设计,在应用程序根目录中配置容器,并且最好在应用程序中只有一个位置来组装类型(阅读: GetInstance 被调用)。对于 ASP.NET MVC 应用程序,这将是 ControllerFactory。对于 ASP.NET WebForms 应用程序,您通常需要覆盖 PageHandlerFactory

当您遵守这些规则时,没有理由使用这样的抽象,因为无论如何您只是在应用程序的一个地方调用容器。但是,如果这对您不可行,则可以使用 Common Service Locator 或您自己的抽象来替代。

但是,在您决定让您的代码依赖于您的 IoC 库的抽象之前,请退后一步,因为这会导致很多问题,而且通常is seen as an anti-pattern。从代码中回调容器:

  • 使代码更难测试。
  • 隐藏依赖项反而使代码更难阅读和维护。
  • 禁用编译时支持。
  • 不允许工具验证您的依赖关系图。

【讨论】:

  • 在外部依赖项周围使用包装器是有意义的,但是,我不知道是否有任何人们切换 IoC 容器的真实实例。
【解决方案2】:

如果您有很多库和基于这些库构建的大量应用程序,您最终会得到大量 IoC 注册代码,这些代码会在所有这些应用程序中重复。

您可以让每个库负责将自己注册到容器中,但随后它必须了解特定的 IoC 实现。或者你可以按照你的建议做,创建一个 IoC 包装器,让你的库负责通过 IoC 包装器注册自己。

【讨论】:

    【解决方案3】:

    优点是您可以轻松地交换 IOC 容器。缺点是您失去了特定于 IOC 容器的任何功能。 MVC 涡轮机使用这种方法。看看它的源代码,看看它是如何处理定位器的。 http://mvcturbine.codeplex.com/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 2018-09-02
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多