Click here to Skip to main content
15,860,972 members
Articles / Web Development / HTML
Tip/Trick

Constructor Dependency Injection Pattern Implementation in C#

Rate me:
Please Sign up or sign in to vote.
4.69/5 (26 votes)
22 Sep 2014CPOL4 min read 77.3K   527   35   10
This tip is about the Constructor Dependency Injection Pattern Implementation in C#.

Introduction

Dependency Injection (DI) is a pattern where objects are not responsible for creating their own dependencies. Dependency injection is a way to remove hard-coded dependencies among objects, making it easier to replace an object's dependencies, either for testing (using mock objects in unit test) or to change run-time behavior.

Before understanding Dependency Injection, you should be familiar with the two concepts of Object Oriented Programming, one is tight coupling and another is loose coupling, so let's see each one by one.

Tight Coupling: When a class is dependent on a concrete dependency, it is said to be tightly coupled to that class. A tightly coupled object is dependent on another object; that means changing one object in a tightly coupled application often requires changes to a number of other objects. It is not difficult when an application is small but in an enterprise level application, it is too difficult to make the changes.

Loose Coupling: It means two objects are independent and an object can use another object without being dependent on it. It is a design goal that seeks to reduce the inter- dependencies among components of a system with the goal of reducing the risk that changes in one component will require changes in any other component.

Now in short, Dependency Injection is a pattern that makes objects loosely coupled instead of tightly coupled. In this tip, you will be the first to introduce tight coupling and thereafter you will introduce loose coupling using the Constructor Dependency Injection Pattern. So let's see that.

Using the Code

To understand the concept of Dependency Injection, create an example that is the Error Log Management. The Error Log Management example describes how to create an error log for the application. There are two types of log management, one is using a text file and the other uses an event viewer.

First of all, create an interface IErrorLogger that has one method to write the error log. This interface will be inherited by other log classes.

C#
using System;  
namespace DependencyInjection  
{  
    public interface IErrorLogger  
    {  
        void LogMessage(Exception ex);  
    }  
}

Now create a class, FileLogger class, that inherits the IErrorLogger interface. This class writes an error log message to a text file.

C#
using System;  
using System.Configuration;  
using System.IO; 
  
namespace DependencyInjection  
{  
    public class FileLogger : IErrorLogger  
    {  
        public void LogMessage(Exception ex)  
        {  
            string folderPath = ConfigurationManager.AppSettings["ErrorFolder"];  
            if (!(Directory.Exists(folderPath)))  
            {  
                Directory.CreateDirectory(folderPath);  
            }  
            FileStream objFileStrome = new FileStream(folderPath + "errlog.txt", FileMode.Append, FileAccess.Write);  
            StreamWriter objStreamWriter = new StreamWriter(objFileStrome);  
            objStreamWriter.Write("Message: " + ex.Message);  
            objStreamWriter.Write("StackTrace: " + ex.StackTrace);  
            objStreamWriter.Write("Date/Time: " + DateTime.Now.ToString());  
            objStreamWriter.Write("============================================");  
            objStreamWriter.Close();  
            objFileStrome.Close();  
        }  
    }

Now create an EventViewerLogger class that inherits the IErrorLogger interface. This class writes an error log message in the event viewer.

C#
using System;  
using System.Configuration;  
using System.Diagnostics;  
  
namespace DependencyInjection  
{  
    public class EventViewerLogger : IErrorLogger  
    {  
        public void LogMessage(Exception ex)  
        {  
            EventLog objEventLog = new EventLog();  
            string sourceName = ConfigurationManager.AppSettings["App"];  
            string logName = ConfigurationManager.AppSettings["LogName"];  
            if (!(EventLog.SourceExists(sourceName)))  
            {  
                EventLog.CreateEventSource(sourceName, logName);  
            }  
            objEventLog.Source = sourceName;  
            string message = String.Format("Message: {0} \n StackTrace: 
            {1} \n Date/Time: {2} ", ex.Message, ex.StackTrace, DateTime.Now.ToString());  
            objEventLog.WriteEntry(message, EventLogEntryType.Error);  
        }  
    }  
}

Now we create another class to understand the concept of tight coupling. The Operation class has an interface, an IErrorLogger instance, created by the FileLogger class. In other words, the Operation class object is tightly coupled with the FileLogger class.

C#
using System;  
  
namespace DependencyInjection  
{  
   public class Operation  
    {  
       IErrorLogger logger = new FileLogger();  
       public void Division()  
       {  
           try  
           {  
               int firstNumber = 15, secondNumber = 0, result;  
               result = firstNumber / secondNumber;  
               Console.WriteLine("Result is :{0}", result);  
           }  
           catch (DivideByZeroException ex)  
           {  
               logger.LogMessage(ex);  
           }  
       }  
    }  
} 

The code above works, but it's not the best design because it is tightly coupled with FileLogger. When you want to use another IErrorLogger implementation class, then you need to change it. That is not depending on the Open Closed Principle of Object Oriented Programming.

Now call your class method in your application startup class and you get a log in the text file so your start up class code is below:

C#
using System;  
namespace DependencyInjection  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Operation objOperation = new Operation();  
            objOperation.Division();  
            Console.Read();  
        }  
    }  
} 

Let's run the application. You will get an exception in the log file such as in Figure 1.1.

Error Log in txt File

Figure 1.1 Error Log in txt File

To solve this problem, you should use constructor dependency injection in which an IErrorLogger is injected into the object.

Constructor Dependency Injection Pattern

This is the most commonly used Dependency Pattern in Object Oriented Programming. The Constructor Injection uses a parameter to inject dependencies so there is normally one parameterized constructor always. So in this constructor dependency, the object has no default constructor and you need to pass specified values at the time of creation to initiate the object.

You can say that your design is loosely coupled with the use of constructor dependency injection.

Now create a class OperationEvent. That class has a parameter constructor. This constructor will be used to inject dependencies in the object. Let's see the following code.

C#
using System;  
  
namespace DependencyInjection  
{  
    public class OperationEvent  
    {  
        IErrorLogger logger;  
  
        public OperationEvent(IErrorLogger logger)  
        {  
            this.logger = logger;  
        }  
  
        public void Division()  
        {  
            try  
            {  
                int firstNumber = 15, secondNumber = 0, result;  
                result = firstNumber / secondNumber;  
                Console.WriteLine("Result is :{0}", result);  
            }  
            catch (DivideByZeroException ex)  
            {  
                logger.LogMessage(ex);  
            }  
        }  
    }  
} 

By the preceding, you have noticed that an OperationEvent object is neither dependent on an FileLogger object nor an EventViewerLogger object so you can inject either FileLogger dependencies or EventViwerLogger dependencies at run time. Let's see the startup class in which we inject EventViewerLogger dependencies in an OperationEvent object using constructor dependency injection.

C#
using System;  
  
namespace DependencyInjection  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            OperationEvent objOperationEvent = new OperationEvent(new EventViewerLogger());  
            objOperationEvent.Division();  
            Console.Read();  
        }  
    }  
}

Let's run the application and you get the results as in Figure 1.2 .

Log Errors in Event Viewer.

Figure 1.2 Log Errors in Event Viewer.

Conclusion

This article has introduced a basic object oriented concept such as tight coupling and loose coupling. I hope you also get an idea of how to manage your application error log and finally you have learned about Constructor Dependency Injection Pattern. I hope it will be helpful for you and if you have any doubt or feedback, then post your comments here or you can directly connect with me at https://twitter.com/ss_shekhawat.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
He is awarded for Microsoft TechNet Guru, CodeProject MVP and C# Corner MVP. http://l-knowtech.com/

Comments and Discussions

 
QuestionConfused... Pin
Member 1199213017-Sep-15 7:17
Member 1199213017-Sep-15 7:17 
QuestionMy Vote of 5! Pin
Ranjith V16-Aug-15 21:09
Ranjith V16-Aug-15 21:09 
GeneralMy vote of 4 Pin
santosh siba2-Jan-15 23:33
santosh siba2-Jan-15 23:33 
GeneralRe: My vote of 4 Pin
Sandeep Singh Shekhawat2-Jan-15 23:46
professionalSandeep Singh Shekhawat2-Jan-15 23:46 
GeneralI vote 5 Pin
Amit Dhakre23-Sep-14 20:02
Amit Dhakre23-Sep-14 20:02 
GeneralRe: I vote 5 Pin
Sandeep Singh Shekhawat27-Nov-14 19:00
professionalSandeep Singh Shekhawat27-Nov-14 19:00 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun22-Sep-14 19:55
Humayun Kabir Mamun22-Sep-14 19:55 
GeneralRe: My vote of 5 Pin
Sandeep Singh Shekhawat27-Nov-14 19:00
professionalSandeep Singh Shekhawat27-Nov-14 19:00 
SuggestionExamples are too simple Pin
Neil Simon8-Jul-14 2:02
Neil Simon8-Jul-14 2:02 
GeneralRe: Examples are too simple Pin
Sandeep Singh Shekhawat8-Jul-14 6:13
professionalSandeep Singh Shekhawat8-Jul-14 6:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.