依赖注入VS服务定位 [英] Dependency Injection vs Service Location

查看:134
本文介绍了依赖注入VS服务定位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前重达DI和SL之间的优点和缺点。然而,我发现自己在下面的抓22这意味着我应该只使用SL的一切,只有注入IoC容器到每个班级。

DI左右为难:

一些依赖,像log4net的,根本不适合DI。我把这些元依赖性,觉得他们应该是不透明的调用code。我的理由是,如果一个简单的类'D',而不记录最初实行,然后长到需要的日志记录,那么相关的类'A','B'和'C',现在必须以某种方式获得这种依赖,从它向下传递'A'至'D'(假设'A'组成'B','B'组成的'C',等等)。现在我们已经取得了只是因为我们在同一个类需要登录显著code的变化。

我们因此要求用于获得元依赖性不透明机制。二浮现在脑海中:辛格尔顿和SL。前者具有已知的限制,主要是关于刚性作用域功能:充其量一个Singleton将使用它存储在应用范围抽象工厂(即在一个静态变量)。这允许有一定的灵活性,但是不完美的。

有一个更好的解决办法是注入IoC容器成这样的类,然后用SL从该类内从容器中解决这些荟萃的依赖关系。

因此​​搭上22:由于类是现在正在使用IoC容器注入的,那么为什么不使用它来解决所有其他依赖太

我将不胜AP preciate您的想法:)


解决方案

  

由于该类现在正在使用IoC容器注入的,那么为什么不使用它来解决所有其他的依赖呢?


使用Service Locator模式完全违背了依赖注入的要点之一。依赖注入的一点是使依赖关系明确。一旦你在构造函数不是让他们明确的参数隐藏这些依赖关系,你不再做全面的依赖注入。

这些是命名的(设置为约翰尼现金歌曲的主题)一类所有构造函数:

错误:

 公共美孚(){
    this.bar =新的酒吧();
}

错误:

 公共美孚(){
    this.bar = ServiceLocator.Resolve<酒吧及GT;();
}

错误:

 公共美孚(服务定位定位器){
    this.bar = locator.Resolve<酒吧及GT;();
}

右:

 公共美孚(酒吧吧){
    this.bar =栏;
}

只有后者使得对酒吧明确。

的依赖

至于记录,有做没有它渗透到您的域名code正确的方式(它不应该,但如果这样做,那么你使用依赖注入周期)。令人惊讶的是,IoC容器中,可以用这个问题有所帮助。这里开始

I am currently weighing up the advantages and disadvantages between DI and SL. However, I have found myself in the following catch 22 which implies that I should just use SL for everything, and only inject an IoC container into each class.

DI Catch 22:

Some dependencies, like Log4Net, simply do not suit DI. I call these meta-dependencies and feel they should be opaque to calling code. My justification being that if a simple class 'D' was originally implemented without logging, and then grows to require logging, then dependent classes 'A', 'B', and 'C' must now somehow obtain this dependency and pass it down from 'A' to 'D' (assuming 'A' composes 'B', 'B' composes 'C', and so on). We have now made significant code changes just because we require logging in one class.

We therefore require an opaque mechanism for obtaining meta-dependencies. Two come to mind: Singleton and SL. The former has known limitations, primarily with regards to rigid scoping capabilities: at best a Singleton will use an Abstract Factory which is stored at application scope (ie. in a static variable). This allows some flexibility, but is not perfect.

A better solution would be to inject an IoC container into such classes, and then use SL from within that class to resolve these meta-dependencies from the container.

Hence catch 22: because the class is now being injected with an IoC container, then why not use it to resolve all other dependencies too?

I would greatly appreciate your thoughts :)

解决方案

Because the class is now being injected with an IoC container, then why not use it to resolve all other dependencies too?

Using the service locator pattern completely defeats one of the main points of dependency injection. The point of dependency injection is to make dependencies explicit. Once you hide those dependencies by not making them explicit parameters in a constructor, you're no longer doing full-fledged dependency injection.

These are all constructors for a class named Foo (set to the theme of the Johnny Cash song):

Wrong:

public Foo() {
    this.bar = new Bar();
}

Wrong:

public Foo() {
    this.bar = ServiceLocator.Resolve<Bar>();
}

Wrong:

public Foo(ServiceLocator locator) {
    this.bar = locator.Resolve<Bar>();
}

Right:

public Foo(Bar bar) {
    this.bar = bar;
}

Only the latter makes the dependency on Bar explicit.

As for logging, there's a right way to do it without it permeating into your domain code (it shouldn't but if it does then you use dependency injection period). Amazingly, IoC containers can help with this issue. Start here.

这篇关于依赖注入VS服务定位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆