Tuesday, May 24, 2016

Dependency Injection Pattern Implementation

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.


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.
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.
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.
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.
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:
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.
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 FileLoggerobject nor an EventViewerLogger object so you can inject either FileLogger dependencies orEventViwerLogger dependencies at run time. Let's see the startup class in which we injectEventViewerLogger dependencies in an OperationEvent object using constructor dependency injection.
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.




CRUD Operations Using the Generic Repository Pattern and Dependency Injection in MVC

24 Dec 2014 CPOL
This article introduces use of the Generic Repository Pattern and Dependency Injection in MVC for CRUD Operations.

Introduction

This is my last article of CRUD Operation series using entity framework code first approach in ASP.NET MVC. In the previous article, I introduced CRUD Operations Using the Generic Repository Pattern and Unit of Work in MVC. This article introduces to you how we can use dependency injection is your application to perform curd operations. To implement Dependency Inject pattern, we will use Ninject Dependency Injector.To know more about dependency injection, you could visit my tip here: Constructor Dependency Injection Pattern Implementation in C#.

Our Roadmap Towards Learning MVC with Entity Framework

Dependency Injection (DI)

Dependency Injection (DI) is a type of IoC, it 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 behaviour.
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. Generally, we create a concrete class object in the class we require the object and bind it in the dependent class but DI is a pattern where we create a concrete class object outside this high-level module or dependent class.
There are three types of dependency injections:
  1. Constructor Dependency Injection
  2. Setter Dependency Injection
  3. Interface Dependency Injection
In this article, we will use Constructor Dependency Injection. This is the most commonly used Dependency Injection Pattern in Object Oriented Programming. The Constructor Dependency 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.

Dependency Injection (DI) Container

The Dependency Injection Container is a framework to create dependencies and inject them automatically when required. It automatically creates objects based on requests and injects them when required. It helps us split our application into a collection of loosely-coupled, highly-cohesive pieces and then glue them back together in a flexible manner. By DI container, our code will become easier to write, reuse, test and modify. In this article, we will use a Niject DI Container.

CRUD Operations Application Design

We create four projects in a solution to implement DIP with generic repository pattern. These are:
  1. Ioc.Core (class library)
  2. Ioc.Data (class library)
  3. Ioc.Service (class library)
  4. Ioc.Web (web application)
Application Project Structure
Figure 1.1: Application Project Structure

Define Entities in Application

In this article, we are working with the Entity Framework Code First Approach so the project Ioc.Core contains entities that are necessary in the application's database. In this project, we create three entities, one is theBaseEntity class that has common properties that will be inherited by each entity and the others are Userand UserProfile entities. Let's see each entity. The following is a code snippet for the BaseEntity class.
using System;
namespace Ioc.Core
{
  public abstract class BaseEntity
    {
      public Int64 ID { get; set; }
      public DateTime AddedDate { get; set; }
      public DateTime ModifiedDate { get; set; }
      public string IP { get; set; }
    }
}
The User and UserProfile entities have a one-to-one relationship. One User can have only one profile.
Relationship between User and UserProfile Entities
Figure 1.2: Relationship between User and UserProfile Entities
Now, we create a User entity under the Data folder of the Ioc.Core project that inherits from the BaseEntityclass. The following is a code snippet for the User entity.
using System;
namespace Ioc.Core.Data
{
   public class User : BaseEntity
    {
       public string UserName { get; set; }
       public string Email { get; set; }
       public string Password { get; set; }
       public virtual UserProfile UserProfile { get; set; }
    }
} 
Now, we create a UserProfile entity under the Data folder of the Ioc.Core project that inherits from theBaseEntity class. The following is a code snippet for the UserProfile entity.
using System;
namespace Ioc.Core.Data
{
  public class UserProfile : BaseEntity
    {
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string Address { get; set; }
      public virtual User User { get; set; }
    }
}

Define Context Class

The Ioc.Data project contains DataContextUser and UserProfile entities Mapping and Repository. The ADO.NET Entity Framework Code First data access approach requires us to create a data access context class that inherits from the DbContext class so we create an interface IDbContext that inherited by context classIocDbContext (IocDbContext.cs) class. In this class, we override the OnModelCreating() method. This method is called when the model for a context class (IocDbContext) has been initialized, but before the model has been locked down and used to initialize the context such that the model can be further configured before it is locked down. First, create an IDbContext interface and the following code snippet for it.
using System.Data.Entity;
using Ioc.Core;
namespace Ioc.Data
{
   public interface IDbContext
    {
        IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;
        int SaveChanges();
    }
} 
Now, create the IocDbContext class and the following code snippet for it.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Ioc.Core;

namespace Ioc.Data
{
    public class IocDbContext : DbContext, IDbContext
    {
        public IocDbContext()
            : base("name=DbConnectionString")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
            type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
         base.OnModelCreating(modelBuilder);
        }

        public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
        {
            return base.Set<TEntity>();
        }
    }
}  
As you know, the EF Code First approach follows convention over configuration, so in the constructor, we just pass the connection string name, the same as an App.Config file and it connects to that server. In theOnModelCreating() method, we used reflection to map an entity to its configuration class in this specific project.

Define Mapping of Entities

Now, we define the configuration for the User and UserProfile entities that will be used when the database table will be created by the entity. The configuration defines the class library project Ioc.Data under theMapping folder. Now create the configuration classes for the entity. For the User entity, we create the UserMapclass and for the UserProfile entity, create the UserProfileMap class.
The following is a code snippet for the UserMap class.
using System.Data.Entity.ModelConfiguration;
using Ioc.Core.Data;

namespace Ioc.Data.Mapping
{
   public class UserMap :EntityTypeConfiguration<User>
    {
       public UserMap()
       {
           //key
           HasKey(t => t.ID);
           //properties
           Property(t => t.UserName).IsRequired();
           Property(t => t.Email).IsRequired();
           Property(t => t.Password).IsRequired();
           Property(t => t.AddedDate).IsRequired();
           Property(t => t.ModifiedDate).IsRequired();
           Property(t => t.IP);
           //table
           ToTable("Users");
       }
    }
} 
The following is a code snippet for the UserProfileMap class.
using System.Data.Entity.ModelConfiguration;
using Ioc.Core.Data;

namespace Ioc.Data.Mapping
{
   public class UserProfileMap : EntityTypeConfiguration<UserProfile>
    {
       public UserProfileMap()
       {
           //key
           HasKey(t => t.ID);
           //properties
           Property(t => t.FirstName).IsRequired().HasMaxLength(100).HasColumnType("nvarchar");
           Property(t => t.LastName).HasMaxLength(100).HasColumnType("nvarchar");
           Property(t => t.Address).HasColumnType("nvarchar");
           Property(t => t.AddedDate).IsRequired();
           Property(t => t.ModifiedDate).IsRequired();
           Property(t => t.IP);
           //table
           ToTable("UserProfiles");
           //relation
           HasRequired(t => t.User).WithRequiredDependent(u => u.UserProfile);
       }
    }
}  

Create Generic Repository

The Repository pattern is intended to create an abstraction layer between the data access layer and the business logic layer of an application. It is a data access pattern that prompts a more loosely coupled approach to data access. We create the data access logic in a separate class, or set of classes, called a repository, with the responsibility of persisting the application's business model.
Now, we create a generic repository interface and class. This generic repository has all CRUD operations methods. This repository contains a parameterized constructor with a parameter as Context so when we create an instance of the repository, we pass a context so that all the repositories for each entity has the same context. We are using the saveChanges() method of the context. The following is a code snippet for the Generic Repository interface.
using System.Linq;
using Ioc.Core;

namespace Ioc.Data
{
    public interface IRepository<T> where T : BaseEntity
    {
        T GetById(object id);
        void Insert(T entity);
        void Update(T entity);
        void Delete(T entity);
        IQueryable<T> Table { get; }
    }
} 
The following is a code snippet for the Generic Repository class that implements the IRepository interface.
using System;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using Ioc.Core;

namespace Ioc.Data
{
   public class Repository<T> : IRepository<T> where T: BaseEntity
    {
        private readonly IDbContext _context;
        private IDbSet<T> _entities;

        public Repository(IDbContext context)
        {
            this._context = context;
        }

        public T GetById(object id)
        {
            return this.Entities.Find(id);
        }

        public void Insert(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this.Entities.Add(entity);
                this._context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                var msg = string.Empty;

                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        msg += string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;
                    }
                }

                var fail = new Exception(msg, dbEx);
                throw fail;
            }
        }

        public void Update(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this._context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                var msg = string.Empty;
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        msg += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
                var fail = new Exception(msg, dbEx);
                throw fail;
            }
        }

        public void Delete(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this.Entities.Remove(entity);
                this._context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                var msg = string.Empty;

                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        msg += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
                var fail = new Exception(msg, dbEx);
                throw fail;
            }
        }

        public virtual IQueryable<T> Table
        {
            get
            {
                return this.Entities;
            }
        }

        private IDbSet<T> Entities
        {
            get
            {
                if (_entities == null)
                {
                    _entities = _context.Set<T>();
                }
                return _entities;
            }
        }
    }
}  

Create Service for User Operations

To implement DIP with DI, we create a service for the user entity that the service communicates with the UI and data access logic. Since DIP states that a high-level module should not depend on a low-level module we define an IUsesService interface in the Ioc.Service project depending on what we need on the UI to do the CRUD operations. The following code snippet is for IUserService.
using System.Linq;
using Ioc.Core.Data;

namespace Ioc.Service
{
   public interface IUserService
    {
       IQueryable<User> GetUsers();
       User GetUser(long id);
       void InsertUser(User user);
       void UpdateUser(User user);
       void DeleteUser(User user);
    }
} 
Now, we create a concrete UserService class that implemented the IUserService interface to do CRUD operations on both User and UserProfile entities using generic repository. The following code snippet is for the UserService class in the same project.
using System.Linq;
using Ioc.Core.Data;
using Ioc.Data;

namespace Ioc.Service
{
public class UserService : IUserService
{
private IRepository<User> userRepository;
private IRepository<UserProfile> userProfileRepository;

public UserService(IRepository<User> userRepository, IRepository<UserProfile> userProfileRepository)
{
this.userRepository = userRepository;
this.userProfileRepository = userProfileRepository;
}

public IQueryable<User> GetUsers()
{
return userRepository.Table;
}

public User GetUser(long id)
{
return userRepository.GetById(id);
}

public void InsertUser(User user)
{
userRepository.Insert(user);
}

public void UpdateUser(User user)
{
userRepository.Update(user);
}

public void DeleteUser(User user)
{
userProfileRepository.Delete(user.UserProfile);
userRepository.Delete(user);
}
}
}

No comments:

Post a Comment