在 ASP.NET Core MVC 中使用依赖注入的好处

Joh*_*ohn 4 c# dependency-injection asp.net-core-mvc

我正在阅读这篇关于在 ASP.NET Core 中使用 DI 的文章 @ https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0 ..但我无法理解它的好处是提供抽象级别。

例如,如果没有 DI,我们将拥有这些类:-

public class MyDependency
{
    public void WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
    }
}

public class IndexModel : PageModel
{
    private readonly MyDependency _dependency = new MyDependency();

    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet");
    }
}
Run Code Online (Sandbox Code Playgroud)

通过 DI,我们将拥有这些课程:-

public interface IMyDependency
{
    void WriteMessage(string message);
}
public class MyDependency : IMyDependency
{
    public void WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
    }
}
public class Index2Model : PageModel
{
    private readonly IMyDependency _myDependency;

    public Index2Model(IMyDependency myDependency)
    {
        _myDependency = myDependency;            
    }

    public void OnGet()
    {
        _myDependency.WriteMessage("Index2Model.OnGet");
    }
}
Run Code Online (Sandbox Code Playgroud)

但在使用 DI 或不使用 DI 的最后,如果我想修改 WriteMessage 方法,接受 2 个字符串而不是一个字符串,如下所示:-

public void WriteMessage(string message,string message2)
        {
            Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}{message2}");
        }
Run Code Online (Sandbox Code Playgroud)

我将不得不修改相关的类;不带 DI 外壳:-

public class IndexModel : PageModel
{
    private readonly MyDependency _dependency = new MyDependency();

    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet","two");
    }
}
Run Code Online (Sandbox Code Playgroud)

带 DI 外壳:-

public class Index2Model : PageModel
{
    private readonly IMyDependency _myDependency;

    public Index2Model(IMyDependency myDependency)
    {
        _myDependency = myDependency;            
    }

    public void OnGet()
    {
        _myDependency.WriteMessage("Index2Model.OnGet","two");
    }
}
Run Code Online (Sandbox Code Playgroud)

所以不确定使用 DI 如何在实现WriteMessage和使用它的类之间创建抽象。或者我错误地理解了 DI 及其好处?

谢谢

kb4*_*000 5

我想指出的是,您不必使用接口来使用依赖注入。你绝对可以,如果你想执行一份合同,而你将来可能有不同的实施,那就太好了。但这不是必需的。您可以在没有接口的情况下注入服务或其他依赖项。

DI 的主要好处之一是您不必手动连接依赖项。在您给出的示例中MyDependency没有任何依赖项。但是,如果它有四个用于其他服务或存储库等的参数呢?现在Index2Model您必须创建所有这些依赖项的实例,并将它们传递到新的MyDependency构造函数中。如果您有更复杂的应用程序,这将变得非常繁重。使用 DI,它只是为您提供一个准备就绪的实例。

另一大问题是范围。我在许多不同的软件产品中看到的一个大问题是意外状态。有人的编码有点草率,并在类中创建了一个变量,如果同一个实例被多个请求使用,则应用程序中可能会出现意外状态。

使用 DI,您可以默认使用瞬态依赖项,每次您使用该依赖项时,它都是一个全新的实例,但您可以轻松切换要限定范围的特定依赖项,从而在 HTTP 请求的生命周期中保留相同的实例,这将很难手动复制,或者您可以在有意义时将其设置为单例。