Thursday, 9 July 2015

Changes required to be done for implementing Dependency injection in WebAPI or MVC project

Below are the changes required to be done for implementing Dependency injection in WebAPI or MVC project.

References required:

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Mvc;
using IOCLibrary;



global.asax changes:
This change is required only for Web project.

public class WebApiApplication : HttpApplication
    {
        protected void Application_Start()
        {
            #region "General settings"
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }


WebApiConfig.cs changes:

In below example, we are implementing Dependency injection on classes which are used for handling requests
(For e.g. Inspector.cs , HttpsRquestValidator.cs).
If there are no such classes in your project then these change is not required.
This change is required only for WebAPI or MVC project.


namespace WebAPITest
{

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var container = UnityConfig.GetConfiguredContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

//To validate request data
            var Inspector = container.Resolve<Inspector>();
            Inspector.InnerHandler = new HttpControllerDispatcher(config);
           
//Global request handler -applicable to all the requests
            var validator = container.Resolve<HttpsRquestValidator>();

            config.DependencyResolver = new IocContainer(container);

            config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }, null, Inspector);

            config.MessageHandlers.Add(validator);
        }
    }
}


//App_Start/UnityWebActivator.cs changes
This change is required only for WebAPI or MVC project.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(UnityWebActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(UnityWebActivator), "Shutdown")]

namespace WebAPITest
{
    /// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
    public static class UnityWebActivator
    {
        /// <summary>Integrates Unity when the application starts.</summary>
        public static void Start()
        {
            var container = UnityConfig.GetConfiguredContainer();

            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
           
        }

        public static void Shutdown()
        {
            var container = UnityConfig.GetConfiguredContainer();
            container.Dispose();
        }
    }
}


// UnityConfig.cs changes
This file is used for maintaining list of all classes used in project with their mapped interface.


public class UnityConfig
    {
        #region Unity Container
        private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });
        public static IUnityContainer GetConfiguredContainer()
        {
            return Container.Value;
        }
        #endregion
       
        public static void RegisterTypes(IUnityContainer container)
        {
            //load classess
            container.RegisterType<HomeController>();
            container.RegisterType<IFileSystem, FileSystem>();
        }
    }


Create IOCLibrary using below classes:
If there are more than project then this library will be useful or you could use below classes in project itself.

public class ScopeContainer : IDependencyScope
    {
        protected IUnityContainer Container;

        public ScopeContainer(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            Container = container;
        }

        public object GetService(Type serviceType)
        {
            if (Container.IsRegistered(serviceType))
            {
                return Container.Resolve(serviceType);
            }
            return null;
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (Container.IsRegistered(serviceType))
            {
                return Container.ResolveAll(serviceType);
            }
            return new List<object>();
        }

        public void Dispose()
        {
            Container.Dispose();
        }
    }

    public class IocContainer : ScopeContainer, IDependencyResolver
    {
        public IocContainer(IUnityContainer container)
            : base(container)
        {
        }

        public IDependencyScope BeginScope()
        {
            var child = Container.CreateChildContainer();
            return new ScopeContainer(child);
        }

    }

No comments:

Post a Comment