Programmerzzz
Programmerzzz

Reputation: 1287

Understanding Dependency Injection, Simple Example

Below is a very basic console App example that I put on understanding Dependency Injection & IOC. I somehow could not see the value as in this case I still need to modify my program.cs to inject the new implementation of Interface. Also, how unit testing fits into this?

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);
            }
        }
    }
}

Here, if I have to swap Messaging.cs implementation with NewMessaging.cs which both implement IMessage interface, I still need to modify my Program.cs to inject this NewMessaging.cs like this:

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

If so, why MS claims that DI addresses one prob of To replace MyDependency with a different implementation, the class must be modified src:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

What am I missing?

Upvotes: 1

Views: 367

Answers (1)

dymanoid
dymanoid

Reputation: 15227

In your example, there is no dependency injection.

Dependency injection literally means: you inject a dependency into a class, you don't construct it yourself and don't actively ask some other component for that dependency.

There is no class in your example that actually has a dependency (except of the Program of course).

The Main method in your Program.cs is a composition root. This is where you wire-up the DI container ("service provider"). Of course, you will need to modify it when you want to change the implementations.

Now, imagine you have a class that does have a dependency IMessage:

class ChatBot
{
    private readonly IMessage message;

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

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

If you replace the IMessage implementation in the composition root, the ChatBot class won't even know it. You don't have to touch that class.

Imagine you have 50 classes that all use IMessage to print messages. Changing the implementation still causes the change in the composition root, but only there. The other 50 classes don't need to be changed.

This also helps you in unit testing. If you want to test the ChatBot class, you can mock the IMessage dependency in a way you need it. You also have a direct knowledge, that the ChatBot class needs an IMessage and nothing besides that. Your code is testable then (no hidden calls to unknown singletons, static classes etc.)

Hope my explanation helps. Consider reading a great book "Dependency Injection in .NET" where you'll find a lot of good ideas about designing maintainable software in .NET.

Upvotes: 1

Related Questions