Should I encapsulate my IoC container?

耗尽温柔 提交于 2019-12-05 05:49:16

Do it later, and only if you actually have the need to change IOC containers.

Pick an IOC container that is non-invasive. That is, one where the objects being connected to each other don't have any dependencies on the IOC container. In this case, there's nothing to encapsulate.

If you have to pick an IOC container that requires that you have dependencies on the container, choose one with the simplest dependencies/API you can. If you need to replace this IOC container (and you probably won't), implement adapters that bridge the new API to the old one.

In other words, let the first IOC container be the one that defines the interfaces for any future container so that you don't have to invent your own, and you can delay any of this sort of work until you absolutely need it.

EDIT:

I don't see a way of guaranteeing type-safety short of either:

  1. Designing a relatively complex implementation of the Builder pattern along with visitor implementations that would write IOC configuration files, or something equivalent.
  2. Implementing a type-safe IOC configuration DSL. (My choice if I had multiple apps that required swappable IOC containers.)

Yeah go for it. It's not a whole lot of extra effort and like you say, it gives you better isolation from third party components.

It also means that you can easily switch out the IoC container if you find something that's better. I recently did this with swapping out the Spring.net IoC container for structuremap.

The ASP.NET MVC Contrib project on codeplex is a pretty good place to start. This is what I based my implementation off.

It's best practice to do something only if there's an actual need for it, and never code something that you guess to be required sometimes in the future (that's the so-called YAGNI-principle). If your architecture is ok, you can easily change the container, if it actually should become necessary...

If you think you need this kind of flexibility, you may look at the Common Service Locator project at CodePlex. It does exactly what you look for: providing a common facade for various IoC containers.

HTH!

Rather than encapsulating the IOC container itself, I prefer to isolate the locus of interaction with the IOC container. For example, in ASP.Net MVC, I generally limit the exposure to the container to the controller factory and the global.aspx.cs file, where it's usually setup.

In my mind, having a lot of code that knows about the IOC container is an antipattern that increases complexity. I've seen a fair amount of code in which objects feel free to ask the IOC container for their dependencies, and then they've basically reduced the IOC container to a high-maintenance Service Locator.

Since IOC containers can resolve dependencies to an arbitrary degree of depth, it's pretty easy to make the controller factory the component that's responsible for involving the inversion of control containers. The constructor for each controller essentially specifies the services/repositories/gateways it needs.

For any of my apps, swapping the IOC container would essentially be a matter of rewriting the code the configures the container (specifies the bindings, etc.) and hooks up the controller factory. For apps exposed as services, the same basic idea should be reasonably manageable, though depending on the constraints of your runtime, you might have to use setter injection rather than constructor injection.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!