我们需要依赖注入的接口吗?

LP1*_*P13 15 asp.net-core-mvc .net-core coreclr asp.net-core

我有一个ASP.NET核心应用程序.该应用程序有很少的辅助类可以完成一些工作.每个类都有不同的签名方法.我在网上看到很多.net核心示例,它们为每个类创建接口,然后使用DI框架注册类型.例如

 public interface IStorage
 {
    Task Download(string file);
 }

 public class Storage
 {
    public Task Download(string file)
    {
    }
 }

 public interface IOcr
 {
     Task Process();
 }

 public class Ocr:IOcr
 {
    public Task Process()
    {

    }
 }
Run Code Online (Sandbox Code Playgroud)

基本上每个接口只有一个类.然后我用DI注册这些类型

 services.AddScoped<IStorage, Storage>();
 services.AddScoped<IOcr,Ocr>();
Run Code Online (Sandbox Code Playgroud)

但是我可以在没有接口的情况下注册类型,这样接口看起来多余 例如

 services.AddScoped<Storage>();
 services.AddScoped<Ocr>();
Run Code Online (Sandbox Code Playgroud)

所以我真的需要接口吗?

Nat*_*ini 21

不,你没有需要依赖注入的接口.但你应该使用它们!

正如您所注意到的,您可以使用服务集合注册具体类型,ASP.NET Core会将它们注入您的类中.简单地创建实例的唯一好处new Storage()服务生命周期管理(瞬态与范围与单例).

但这只是使用DI的一部分功能.正如@DavidG指出的那样,接口经常与DI配对的重要原因是测试.使您的类依赖于接口(抽象)而不是其他具体类使它们更容易测试.

对于您的测试,您可以创建一个MockStorage实现IStorage,并且您的消费者类不应该能够分辨出来.或者,您可以使用模拟框架轻松创建模拟IStorage.用具体的类做同样的事情要困难得多.模拟框架要么不支持伪造具体类,要么非常尴尬.接口更简单,更清洁.


Min*_*ata 10

它有用吗?是.你应该这样做吗?没有.

依赖注入是依赖性反转原则的工具:https://en.wikipedia.org/wiki/Dependency_inversion_principle

或者正如它在SOLID中所描述的那样

一个人应该"依赖于抽象,[而不是]具体结果."

可以在整个地方注入具体的课程,它会起作用.但这不是DI旨在实现的目标.

  • 依赖注入不是依赖倒置的工具。这两个概念经常齐头并进(这是正确的),但你可以在没有另一个的情况下完成其中一个。 (6认同)
  • 但是,如果您使用其他人创建的某些“组件”(没有接口),您可能别无选择,对吧? (3认同)
  • 在这种情况下,您可以为该组件创建一个接口。应该是一个 ctrl + . 离开 (2认同)