Wednesday, 17 February 2016

Dependency Injection in MVC using Unity


What is dependency Injection?

Dependency Injection makes your application as decoupled and loosely couple to your code. It use to resolving the dependency of your code. It follow the Dependency Inversion principle of SOLID.
This is the way of injecting the code based on the feature required in application.
There are basically three ways you can approach to implement the dependency Injection.

1.       Using Property Getter and setter
2.       Using Constructor.
3.       Through Interface.


How Implement the Dependency Injection in MVC using Unity?




1.       Take the reference of latest Unity DLL from the nugget package. Open the nugget package manager and search with unity.
As I have already taken the reference it is showing as selected.

Now you can the Unity Dll in reference as like below


2.       We are trying to achieve the way of logging or sending the mail to the Client using the Dependency injection.
3.       Let’s create an Interface which is having a method as log the message with error code.
Interface as ILogger,
namespace DependencyInjection.Service
{
    public interface ILogger
    {
        string LogWithMessage(string ErrorCode, string Errormessage);
    }
}

4.       Now derived the two classes from interface as ILogger as;

a.      Logging Error into File:

   public class LoggingErrorinFile : ILogger
    {
        public string LogWithMessage(string ErrorCode, string Errormessage)
        {
            return string.Format("Looging Error message in file by {0} - {1}", ErrorCode, Errormessage);
        }
    }

b.      Logging Error into Mail:
public class LoggingErrorinMail : ILogger
    {

        public string LogWithMessage(string ErrorCode, string Errormessage)
        {
            return string.Format("Looging Error message in Email by {0} - {1}", ErrorCode, Errormessage);
        }
    }

Now you can see the code structure as  

5.       Add the configuration file for your dependency configuration add file into App_Start folder as DependencyConfigurator.cs
If you will see the below code you can find out how you are injecting the class into dependency injection; You are registering the type of interface with the class that you are going to inject.         
 container.RegisterType<ILogger, LoggingErrorinFile>();

Code Snippet
     public static void ConfigureUnityservice()
        {
            IUnityContainer container = new UnityContainer();
            RegisterService(container);
            DependencyResolver.SetResolver(new DependencyUnityResolver(container));

        }

        /// <summary>
        /// Registering the service that you want to pull
        /// </summary>
        /// <param name="container"></param>
        private static void RegisterService(IUnityContainer container)
        {
            container.RegisterType<ILogger, LoggingErrorinFile>();
        }

6.       Need to Invoke  that Dependency configurator in application start of your Global.asax.cs file like below along with the other configurations.

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            DependencyConfigurator.ConfigureUnityservice();
        }

7.       Now you need a Dependency resolver class which will basically solve your problem of dependency based on the request you have raised for. It is basically common code you don’t need to change if you don’t have any custom requirement.


Just need to inherit the IDependencyResolver interface.
Code Snippet:
namespace DependencyInjection.Infrastructure
{
    public class DependencyUnityResolver : IDependencyResolver
    {

        private IUnityContainer _unityContainer;

        public DependencyUnityResolver(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }

        /// <summary>
        /// It use to return service and if it wont find service it will returns null
        /// </summary>
        /// <param name="serviceType"></param>
        /// <returns></returns>
        public object GetService(Type serviceType)
        {
            try
            {
                return _unityContainer.Resolve(serviceType);
            }
            catch (Exception)
            {

                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _unityContainer.ResolveAll(serviceType);
            }
            catch (Exception)
            {

                return new List<object>();
            }
        }
    }
}

8.       As I told there are three ways to achieve the dependency Injection we are using the constructor based dependency injection on our code so follow the below code for it.
I have the HomeController class.

Step 1: Creating the variable for interface
Step 2: Assign the type when invoking the HomeController class.
Step 3: Now when you call _logProvider.LogWithMessage it based on 5 point it will execute the behaviour of logging either mail send or logging.  It will call LoggingErrorinFile.
As container.RegisterType<ILogger, LoggingErrorinFile>();
public class HomeController : Controller
    {
        // Step 1:
        protected readonly ILogger _logProvider;

        public HomeController() { }

        // Step 2 :
        public HomeController(ILogger log)
        {
            this._logProvider = log;
           
        }
      
        public ActionResult Index()
        {
            // step 3 :
            string loggingMessage = _logProvider.LogWithMessage("8888","Error message Logged");
            return View();
        }
}

9.       Now run your application and you will find how it work.
You can download the code from below link.


Special thanks to Raghavendra who help to create this article.


No comments:

Post a Comment