Понимание внедрения зависимостей, простой пример - PullRequest
0 голосов
/ 16 марта 2020

Ниже приведен очень простой пример c консольного приложения, который я использовал для понимания Dependency Injection & IO C. Я почему-то не смог увидеть значение, так как в этом случае мне все еще нужно изменить свой program.cs, чтобы внедрить новую реализацию интерфейса. Кроме того, как модульное тестирование вписывается в это?

Program.cs

using Microsoft.Extensions.DependencyInjection;

namespace UnderstandingDI
{
    class Program
    {
        static void Main(string[] args)
        {
            var serPro = new ServiceCollection()
                .AddSingleton<IMessage, Messaging>()
                .BuildServiceProvider();
            var bar = serPro.GetService<IMessage>();
            bar.PrintMessage("Hello World!----");
        }
    }
}

IMessage.cs

namespace UnderstandingDI
{
    public interface IMessage
    {
        public void PrintMessage(string Msg);
    }
}

Messaging.cs

using System;

namespace UnderstandingDI
{
    public class Messaging : IMessage
    {
        public void PrintMessage(string Msg)
        {
            Console.WriteLine(Msg + "From Messaging");
        }
    }
}

NewMessaging.cs

using System;

namespace UnderstandingDI
{
    class NewMessaging : IMessage
    {
        public void PrintMessage(string Msg)
        {
            if (Msg.StartsWith("Hello"))
            {
                Console.WriteLine("Msg starting with Hello");
            }
            else
            {
                Console.WriteLine(Msg);
            }
        }
    }
}

Здесь, если мне нужно поменять Messaging.cs реализацию с NewMessaging.cs, в которой реализован интерфейс IMessage, мне все равно нужно изменить Program.cs, чтобы добавить этот NewMessaging.cs вот так:

var serPro = new ServiceCollection()
                .AddSingleton<IMessage, NewMessaging>()
                .BuildServiceProvider();

Если так, то почему MS утверждает, что DI обращается к одному пробу To replace MyDependency with a different implementation, the class must be modified ср c: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

Чего мне не хватает?

1 Ответ

1 голос
/ 16 марта 2020

В вашем примере нет внедрения зависимостей.

Внедрение зависимостей буквально означает: вы внедряете зависимость в класс, вы не создаете ее сами и не активно попросите другой компонент для этой зависимости.

В вашем примере нет класса, который действительно имел бы зависимость (кроме, конечно, Program).

В вашем методе Main Program.cs является композицией root. Здесь вы подключаете контейнер DI («поставщик услуг»). Конечно, вам нужно будет изменить его, когда вы захотите изменить реализации.

Теперь представьте, что у вас есть класс, который имеет зависимость IMessage:

class ChatBot
{
    private readonly IMessage message;

    public ChatBot(IMessage message) => _message = message;

    public void Greet() => _message.PrintMessage("Hello World!");
}

Если вы замените реализацию IMessage в составе root, класс ChatBot даже не узнает об этом. Вам не нужно трогать этот класс.

Представьте, что у вас есть 50 классов, которые все используют IMessage для печати сообщений. Изменение реализации по-прежнему вызывает изменение состава root, , но только там . Другие 50 классов не нужно менять.

Это также поможет вам в модульном тестировании. Если вы хотите проверить класс ChatBot, вы можете смоделировать зависимость IMessage так, как вам нужно. У вас также есть прямое знание, что ChatBot класс нуждается в и IMessage и ничего кроме этого. Ваш код может быть проверен (никаких скрытых вызовов неизвестным одиночным, статусам c классы и т. Д. c.)

Надеюсь, мое объяснение поможет. Вы можете прочитать большую книгу «Внедрение зависимостей в. NET», где вы найдете много хороших идей о разработке поддерживаемого программного обеспечения. NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...