RSS

Dependency Injection

17 Apr

I’d like to refactor a simple code sample to demonstrate what dependency injection is. Here I have a MessageSender class to send messages. To send a TextMessage it needs a TextMessage instance.

public class MessageSender
{
    public void SendMessage()
    {
        TextMessage myTextMessage = new TextMessage();
        myTextMessage.Send();
    }
}

public class TextMessage
{
    public void Send()
    {
        // Implements Send()
    }
}

This way the MessageSender depends completely on TextMessage. What if there’s another type named ImageMessage to be sent? I’ll have to modify the SendMessage() method like this:

        ImageMessage myImageMessage = new ImageMessage();
        myImageMessage.Send();

I want the MessageSender be more flexible. In order to achieve loose coupling, I try to make the components independent from each other through the IMessage interface.

public class MessageSender
{
    public void SendMessage()
    {
        IMessage myTextMessage = new TextMessage();
        myTextMessage.Send();
    }
}

public interface IMessage
{
    void Send();
}

public class TextMessage : IMessage
{
    public void Send()
    {
        // Implements Send()
    }
}

Now I have made MessageSender send message through the IMessage interface, but now MessageSender depends on both IMessage and TextMessage. This problem can be solved using dependency injection (DI), A.K.A. inversion of control (IoC).

public class MessageSender
{
    private IMessage myMessage;

    public MessageSender(IMessage newMessage)
    {
        this.myMessage = newMessage;
    }

    public void SendMessage()
    {
        this.myMessage.Send();
    }
}

public interface IMessage
{
    void Send();
}

public class TextMessage : IMessage
{
    public void Send()
    {
        // Implements Send()
    }
}

public class ImageMessage : IMessage
{
    public void Send()
    {
        // Implements Send()
    }
}

The dependency of MessegaSender and TextMessage has been removed by injecting an IMessage instance using its constructor. This is called constructor injection. We can also use a public property to remove dependencies and it’s called setter injection. At this stage the MessageSender no longer has to create the object which implements IMessage.

 
Leave a comment

Posted by on April 17, 2012 in .NET, C#, Design Pattern

 

Tags: , , , ,

Leave a comment