Dependency Injection

Why is it useful and how we can implement it ?

By applying DI ( Dependency injection )  we avoid creating a hard-coded dependency in our classes.

For example, let’s consider the situation where we implement a simple logging system which logs to a text file

We would write a class called FileLogger which could look like this :

public class FileLogger
{
    public LogMessage(string message)
    {
           //some logging code
    }
}

We use it in our code, let’s imagine we have a class which needs to log something :

public class WorkClass
{
     //some properties and methods

     public WorkClass()
     {
           //some code for this constructor
     }

     public void DoesSomethingAndLogs()
     {
            FileLogger fileLogger = new FileLogger();
            filelogger.LogMessage("a message");
     }
}

What we have now is a class with a hard-coded dependency. Why is this bad ?

Well, let’s imagine some real life scenarios. For example, what happens if later on we want to change the logging method from file to database, or we want to unit test the code.

We need a method of being able to tell the system which logging system to use, preferably without us having to go in and modify any code. Just imagine you work on a big project with lots of classes, all of them using logging. The last thing you want is go and change all of them should you decide to log to the database for example.

In order to accomplish this, we need to change the code a little so that we achieve a clear separation of concerns.

Step 1. Code against an interface.

First we create an interface for our logging system :

public interface ILogger
{
      void LogMessage(string message)
}

Step 2. Write an implementation of this interface which writes to files :

public FileLogger : ILogger
{
    LogMessage(string message)
    {
          //some code which writes the message to a text file
    }
}

Step 3 Re-write our WorkClass to use the interface and use DI in the process :

public class WorkClass
{
     ILogger logger;
     //some otherproperties and methods

    public WorkClass(ILogger logger)
    {
         this.logger = logger;
    }

    public ILogger GetLogger()
    {
        return this.logger;
    }

     public void DoesSomethingAndLogs()
     {            
            this.logger.LogMessage("a message");
     }
}

We have now used DI, the constructor takes an interface as a parameter, which could be any implementation of the ILogger interface.

The point is that now we don’t have a hard-coded dependency anymore. We can change the implementation, we can unit test it etc.

In another article we will look at how to set a specific interface implementation to be used by all our classes in the entire project.

Advertisement

About eidand

Senior Dot Net developer specialised in C# / Sql Server / Mvc / Wcf
This entry was posted in Code and tagged , , . Bookmark the permalink.

4 Responses to Dependency Injection

  1. DavidLerma says:

    Good explanation!!

  2. eidand says:

    thank you, I hope it explained well enough so the benefit of using DI is clear even if a change in the software may not be considered. It’s better to be prepared, in case things change and let’s face it, things change a lot during development and maintenance of an application.

    • DavidLerma says:

      i have a question… in this constructor:

      public WorkClass(ILogger logger)
      {
      this.logger = logger;
      }

      where do you create an instance of Logger interface before passing as a parameter?? how is it created?

      Like this??:

      ILogger logger = new FileLogger ()

  3. eidand says:

    good question. You can simply use :

    var logger = new FileLogger();

    and then pass that as the parameter in the constructor :

    var workClass = new WorkClass(logger);
    or in one line :

    var workClass = new WorkClass( new FileLogger());

    now, let’s say you want to actually use this logger into a nicer way, a reusable way and you do not want to pass it to any class, but you want all your classes to use it.

    In this case I would create a static initialization class something like this :

    public static class BaseClass
    {
    public static ILogger Logger { get;set; }
    }

    this class now gives you the one logger instance you can use anywhere.

    You initialize it with whatever logger you want, let’s say in Global.asax in Application_Start :

    BaseClass.Logger = new FileLogger();

    now every other class can simply use BaseClass.Logger and it’s always the file logger one.

    so now if you want to have a DatabaseLogger, you only need to write that implementation, change global.asax to use the new one and all your code continues to work without any other change, because your code simply cares about the contract not the actual implementation. An interface is simply a contract which states that every implementing class must implement what’s in the interface. You’ve decoupled everything so you don’t use a concrete class in any other class that needs to log stuff. The one place in global asax is the only place where you have a concrete class.

    Makes sense ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s