代码之家  ›  专栏  ›  技术社区  ›  Ryan Emerle

我应该封装我的IOC容器吗?

  •  7
  • Ryan Emerle  · 技术社区  · 15 年前

    我正试图决定是否有必要通过额外的努力来封装我的IOC容器。经验告诉我,我应该在应用程序和任何第三方组件之间放置一层封装。我只是不知道这是否接近于过度杀人。

    我可以想到我可能想要切换容器的情况。例如,我当前的容器停止维护,或者证明另一个容器更轻/性能更好,更适合我的需要。如果发生这种情况,那么我可能要做很多重新布线。

    很明显,我正在考虑封装注册信息 类型的解析。我认为封装解决方案是一件轻而易举的事情——我希望有一个助手/util类委托给容器是一种常见的做法。

    编辑:

    假设是为了类型安全性、编译时检查和可重构性,我更喜欢通过编程方式连接类型。它是 代码及其对容器的依赖性,我希望保护自己不受此影响。

    我还为其他几个共享很多相同关系的项目使用了一个IOC容器,但是这个容器很难使用,所以我想要改变。但是,更改意味着我失去了注册码的可重用性。因此,我为什么要考虑封装。这不是一个巨大的负担,但我想减轻它。

    我正在寻找:

    • 最小化容器/容器版本更改的影响
    • 在可能使用不同容器的项目之间提供某种程度的类型注册一致性
    • 提供对我有意义的接口方法(registersingleton<t,t>而不是registertype<t,t>(somelifetimeprovider)-以Unity为例。
    • 随着条件/可伸缩性需求的变化(例如,在解析/注册期间添加更好的缓存、日志记录等)增加容器。
    • 提供我自己的模型来注册类型映射。
      • 假设我想在一个程序集/包中创建一组RegistrationHandler对象,这样我就可以轻松地跨多个类分离注册职责,并在不更改任何其他代码的情况下自动获取这些处理程序。

    我知道这有点主观,所以利弊可能会有所帮助

    谢谢!

    4 回复  |  直到 9 年前
        1
  •  7
  •   Doug Knesek    9 年前

    以后再做,只有当你真的需要改变IOC容器的时候。

    选择一个非侵入性的IOC容器。也就是说,其中相互连接的对象不依赖于IOC容器。在这种情况下,没有什么可以封装的。

    如果您必须选择一个IOC容器,它要求您对该容器具有依赖性,请选择一个依赖性/API最简单的容器。如果您需要替换这个IOC容器(可能不会),请实现将新的API连接到旧的API的适配器。

    换句话说,让第一个国际奥委会集装箱成为 定义 任何未来容器的接口,这样您就不必自己发明,并且您可以延迟任何此类工作,直到您绝对需要它为止。

    编辑:

    我看不出一种保证类型安全的方法,除了:

    1. 设计一个相对复杂的构建器模式实现,以及编写IOC配置文件或类似文件的访问者实现。
    2. 实现类型安全的IOC配置DSL。(如果我有多个需要可交换IOC容器的应用程序,我的选择。)
        2
  •  1
  •   lomaxx    15 年前

    是的,去吧。这并不是很多额外的工作,正如您所说,它使您更好地与第三方组件隔离。

    这也意味着,如果你找到更好的东西,你可以很容易地关掉IOC容器。我最近用spring.net ioc容器替换了structuremap。

    这个 ASP.NET MVC Contrib codeplex上的项目是一个很好的起点。这就是我实现的基础。

        3
  •  1
  •   Thomas Weller    15 年前

    最好的做法是只在有实际需要的情况下才做一些事情,而且永远不要编写一些你认为将来有时需要的代码(这就是所谓的 YAGNI -原则。如果您的体系结构正常,您可以很容易地更改容器,如果它真的需要的话…

    如果你认为你需要这种灵活性,你可以看看 Common Service Locator project 在CODULTEX。它完全符合您的期望:为各种IOC容器提供一个通用的外观。

    啊!

        4
  •  1
  •   JasonTrue    14 年前

    与其封装IOC容器本身,我更喜欢隔离与IOC容器交互的轨迹。例如,在ASP.NET MVC中,我通常限制容器对控制器工厂和global.aspx.cs文件(通常在其中设置)的暴露。

    在我看来,拥有许多了解IOC容器的代码是一个增加复杂性的反模式。我已经看到了相当多的代码,在这些代码中,对象可以自由地向IOC容器请求它们的依赖性,然后它们基本上将IOC容器减少到一个高维护服务定位器。

    由于IOC容器可以将依赖性解析到任意深度,所以很容易使控制器工厂成为涉及控制容器反转的组件。每个控制器的构造函数基本上指定了它需要的服务/存储库/网关。

    对于我的任何应用程序,交换IOC容器本质上都是重写代码、配置容器(指定绑定等)和连接控制器工厂。对于暴露为服务的应用程序,同样的基本思想应该是可以合理管理的,尽管根据运行时的限制,您可能需要使用setter注入,而不是构造函数注入。