且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ASP.NET Core DI 构造函数与 RequestServices

更新时间:2023-02-15 23:20:50

为什么通过 HttpContext.RequestServices 或 IServiceProvider 请求服务被认为是不好的做法.

Why is requesting services via HttpContext.RequestServices or IServiceProvider consider bad practise.

它被认为是一种不好的做法,因为它是 Service Locator anti-模式.

It's considered a bad practice because it is an implementation of the Service Locator anti-pattern.

您试图通过将许多公共依赖项和公共逻辑移动到基类中来保持控制器类较小,但这本身就是一种反模式,因为:

You are trying to keep your controller classes small by moving many common dependencies and common logic into the base class, but that is an anti-pattern by itself, because:

  • 即使从基类解析依赖项,这些依赖项仍然是隐藏的,如 这篇文章 解释了.这意味着依赖项对您的单元测试和 DI 容器是隐藏的,他们将无法对您的对象图进行分析.
  • 将依赖项移至基类并不会降低类的复杂性,因为基类始终与派生类强耦合.
  • 它导致许多职责被塞进基类,这将导致基类违反单责任原则.这会迫使基类成为神类并不断变化.
  • Even though dependencies are resolved from the base class, those dependencies are still hidden, as this article explains. This means dependencies are hidden from your unit tests and from the DI Container, who will be unable to do analysis on your object graphs.
  • Moving dependencies to the base class doesn't lower the complexity of a class, since the base class is always strongly coupled with the derivative.
  • It causes many responsibilities to be crammed into the base class, which will cause the base class to violate the Single Responsibility Principle. This can force the base class to become a god class and under constant change.

基类使用继承,而软件开发中的普遍共识是您应该支持组合胜于继承一>.

Base classes use inheritance, while the general consensus in software development is that you should favor Composition over inheritance.

既然你应该支持组合,这会自动导致依赖注入.在没有基类的情况下,发现违反单一职责原则的行为立即变得更加容易,因为您的构造函数将获得更多参数.再次注意,使用 Service Locator 时依赖项的数量不会改变,只是更难计算.

Since you should favor composition, this automatically leads to Dependency Injection. Without having a base class, it immediately becomes easier to spot Single Responsibility Principle violations, because your constructors will get more arguments. Note again that the number of dependencies doesn't change when using Service Locator, they are just harder to count.

你应该接受这样一个事实,即构造函数注入很容易导致 构造函数超过-injection,因为这表明我们的类做了太多事情,并且表明我们应该重新设计这样的类.

You should embrace the fact that Constructor Injection easily leads to Constructor over-injection, since this is an indication that our class does too much and it is a signal that we should redesign such class.

而不是实施横切关注点,例如在一个基类,使用组合实现它们.例如,您可以使用中间件装饰器拦截器 将横切关注点应用于请求(或此类请求的特定服务).

Instead of implementing cross-cutting concerns such as logging, caching, and authorization in a base class, implement them using composition. For instance, you can use middleware, decorators or interceptors to apply cross-cutting concerns to a request (or a specific service of such request).