【问题标题】:Adding a implementation rather than its interface in ASP.NET Core DI在 ASP.NET Core DI 中添加实现而不是其接口
【发布时间】:2018-08-16 23:01:03
【问题描述】:

添加一个实现而不是它的接口有什么区别,因为我只有这个接口的一个实现?

// Adds a transient service by type of the implementation:
services.AddTransient(typeof(SomeConcreteService));

// Adds a transient service by interface of the concrete implementation type:
services.AddTransient<ISomeService, SomeConcreteService>();

【问题讨论】:

标签: c# asp.net-core dependency-injection


【解决方案1】:

今天你有一个接口的实现。明天你可能不会。其他人将来可能需要使用decoratorcomposite 或其他设计模式来扩展服务。

从本质上讲,通过使用接口,您的应用程序可以应对各种可能性 - 它甚至可以以您今天无法预见的方式进行扩展,而无需更改 DI 容器注册之外的任何一行代码。

如果使用具体类型,扩展它的能力非常有限。您基本上是在说“这将是永远的方式”,而不允许在不更改代码的情况下扩展它的许多可能性。您正在放弃使用 DI 模式最有用的好处 - 通过将其接口与其实现分离来松散耦合您的代码。

【讨论】:

    【解决方案2】:

    当您添加实现时,您只能将其作为实现注入。

    services.AddTransient(typeof(SomeConcreteService));
    

    现在将其作为ISomeService 注入将导致错误。

    此时

    services.AddTransient<ISomeService, SomeConcreteService>();
    

    将允许您注入接口而不是实现。

    最后是关于loosley coupeling。它还使您的软件更难测试。

    如果您只注入接口,您可以轻松地测试使用具有给定接口的实现的类 bc 您可以毫无问题地模拟它。如果您不注入真正的实现,则必须将实现的功能标记为虚拟以模拟它们。您还需要模拟您的实现 SomeConcreteService 可能正在使用的类。

    【讨论】:

      【解决方案3】:
      services.AddTransient<ISomeService, SomeConcreteService>();
      

      这种方式是首选,因为它可以让您以正确的方式使用依赖注入。

      如果您在所有控制器中使用接口,然后决定要更改具体实现,则只需编辑 Startup.cs 中的一行

      public HomeController(ISomeService someService)
      {
            //..
      }
      

      【讨论】:

        猜你喜欢
        • 2017-04-28
        • 2018-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多