如果什么依赖注入是不可能的? [英] What if Dependency Injection is not possible?

查看:118
本文介绍了如果什么依赖注入是不可能的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在多踢和尖叫,我开始接受DI尽管作为依赖增长多少清洁SL看起来可能。

After much kicking and screaming, I'm starting to accept DI despite how much cleaner SL may seem as dependencies grow.

不过,国际海事组织仍然有显著表明,塞与问候DI:

However, IMO there's still a significant show-stopper with regards to DI:

DI是不可能的,当你没有对某个对象的实例化控制在ASP.NET的世界里,例子包括:。的HttpModule,HttpHandler的,页等

DI is not possible when you don't have control over an object's instantiation. In the ASP.NET world, examples include: HttpModule, HttpHandler, Page, etc.

在上面的场景中,我们将采取静态服务点解决依赖关系,通常是通过 HttpContext.Current ,它总是从当前线程推断范围。所以,如果我们要在这里使用静态SL,又何尝不是其他地方也使用它?

In the above scenario we would resort to static service location to resolve dependencies, typically via HttpContext.Current, which invariably infers scope from the current thread. So if we're going to use static SL here, then why not use it else where too?

就是答案简单:咬紧牙关和使用SL在必要时(如上面),但尝试和青睐DI?如果是这样:不使用静态SL只是一次可能会破坏整个应用程序的一致性?从本质上讲撤消DI辛勤工作在其他地方?

Is the answer as simple as: grit your teeth and use SL when necessary (like above), but try and favor DI? And if so: doesn't using static SL just once potentially break the consistency of an entire application? Essentially undoing the hard work of DI everywhere else?

推荐答案

有时候,你只是无法避免紧密耦合,就像在你的例子。然而,这并不意味着你需要或者接受它。相反,通过封装混乱,并从你的一天到一天的生活保理它扔掉隔离它。

Sometimes you just can't avoid tight coupling, like in your examples. However, that doesn't mean you need to embrace it either. Instead, quarantine it by encapsulating the messiness and factoring it away from your day-to-day life.

例如,如果我们想在当前窗体身份验证的用户,我们没有太多的选择,但访问 HttpContext.Current.Request.User.Identity.Name 。但我们确实,有哪里打这通电话的选择。

For example, if we want the current Forms Authentication user, we don't have much choice but to access HttpContext.Current.Request.User.Identity.Name. We do, however, have the choice of where to make that call.

HttpContext.Current 是一个问题的解决方案。当我们直接从我们使用的结果称呼它,我们宣​​布在同一个地方的问题和解决方案:我需要它宣布毫不动摇地从当前HTTP上下文来的当前用户名。此muddles两者的定义,并且不允许用于向同一个问题的不同的解决方案。

HttpContext.Current is a solution to a problem. When we call it directly from where we use the results, we are declaring the problem and solution in the same place: "I need the current user name which is declared unwaveringly as coming from the current HTTP context." This muddles the definition of both and doesn't allow for different solutions to the same problem.

我们缺少的是我们解决问题的明确阐述。在这个例子中,它会是这样的:

What we are missing is a clear articulation of the problem we are solving. For this example, it would be something like:

确定这使得当前请求的用户

Determine the user which made the current request

这是我们使用 HttpContext.Current ,甚至是一个用户名的事实,是不是核心问题定义的一部分;这是一个实现细节,仅提供给code要求当前用户复杂。

The fact that we are using HttpContext.Current, or even a user name, is not a part of the core problem definition; it is an implementation detail that only serves to complicate the code requiring the current user.

我们可以重新present意图获取当前用户,SANS实施细则,通过一个接口:

We can represent the intent to retrieve the current user, sans implementation details, through an interface:

public interface IUserContext
{
    User GetUser();
}

任何类我们叫做 HttpContext.Current 现在可以直接使用此接口代替,由容器注入,以保持DI善良。这也更加用心,露出了一类以接受 IUserContext 在其构造比有哪些不能从它的公共API看到的依赖。

Any class where we called HttpContext.Current directly can now use this interface instead, injected by the container, to maintain DI goodness. It is also much more intention-revealing for a class to accept an IUserContext in its constructor than to have a dependency which can't be seen from its public API.

实施埋在一个地方的静态调用它不能造成任何伤害我们的对象更多:

The implementation buries the static call in a single place where it can't harm our objects any more:

public class FormsUserContext : IUserContext
{
    private readonly IUserRepository _userRepository;

    public FormsUserContext(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public User GetUser()
    {
        return _userRepository.GetByUserName(HttpContext.Current.Request.User.Identity.Name);
    }
}

这篇关于如果什么依赖注入是不可能的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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