如何解耦IoC框架实现

Ric*_*ard 15 c# enterprise-library dependency-injection inversion-of-control unity-container

我一直在学习IoC,依赖注入等,并享受这个过程.对我来说,解耦和编程接口的好处是不费吹灰之力的.

但是,我真的不喜欢将自己绑定到像Unity或Autofac或Windsor这样的特定框架 - 因为我还在学习并且尚未确定哪个最适合我的目的.

那么,我怎么能把像Unity这样的东西包裹起来,这样我以后就可以轻松换掉温莎呢?(管他呢).并且你不敢说用另一个注入第一个;)

谢谢!

R.

Ps我标记Unity,因为这是我目前的个人偏好(我只是在使用Entlib).

def*_*mer 18

使用构造函数注入来传达类所需的依赖项.您列出的每个容器都支持它.

有时,一段代码无法实现完全的容器独立性,但这些情况应该只是代码库的一小部分.

  • 绝对正确的选择构造函数注入. (5认同)

ole*_*sii 18

你当然可以尝试通过声明使得从容器的抽象IContainer与说ResolveRegister.我这样做了几次.然后你将继续实现一个Container:IContainer并用你的抽象封装一个实际的IoC容器.我和Unity和Castle Windsor一起尝试过.

但是,很快,我意识到这真的是一种过度工程化的问题.然后我明白我试图从抽象中抽象出来,然后构建另一个抽象.这可以很好地学习这个概念,但在真正的项目中,这是一个真正的痛苦.我强烈建议不要从IoC容器中抽象出来.如果您正确使用DI原则,无论如何都可以很容易地更换容器.

代码看起来过于复杂,比如

//I did this mess with Service Locator
var t = ContainerService.Instance.Resolve<IMyType>();
//others could go further with same Service Locator
var t = IoCFactory.Instance.CurrentContainer.Resolve<IMyType>();

//better way, use --> IoC and DI <--
//when a program starts, or a new instance of the context created
var t = Container.Resolve<IMyType>() //this lives at the bottom of the stack
//and then you just pass IMyType to the constructor of other types    
//you don't need to call Resolve again in the logical cycle
Run Code Online (Sandbox Code Playgroud)

看Ayende的这篇文章.

是的,他们抽象了反转控制容器.我认为如果你需要这样做,很明显你并没有真正得到IoC的全部内容.

  • @Richard的观点是,即使在最复杂的主动引用容器的项目中,也应该只有少数几个类.其他一切都应该将其依赖注入其中.因此,没有必要抽象它. (4认同)

Tru*_*ill 10

DI容器只能从Composition Root引用.所有其他模块都不应该引用容器.

-Mark Seemann(.NET中依赖注入的作者)

换句话说,如果更改DI容器,则只需要更改一个类.

正如其他人所提到的,构造函数注入通常是正确的方法.Func<T>如果需要动态创建对象,可以注入工厂接口或委托.

我还建议尽可能避免使用XML配置.