This is a simple tutorial in how to use Dependency Injection using SimpleInjector (You can get this package from NuGet)
In this case, I use SimpleInjector to manage my Data Context – I want my Data Context to be per request (Unit of Work per request). The concept of this dependency Injection is to have a global container where you can resolve your object from
1. Create an extension method to the Simple Injector
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using SimpleInjector;
- using System.Diagnostics;
- using System.Linq.Expressions;
- ///<summary>
- /// Extension methods for registering types on a per web request basis.
- ///</summary>
- public static partial class SimpleInjectorPerWebRequestExtensions
- {
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TService, TImplementation>(
- this Container container)
- where TService : class
- where TImplementation : class, TService
- {
- Func<TService> instanceCreator =
- () => container.GetInstance<TImplementation>();
- container.RegisterPerWebRequest<TService>(instanceCreator);
- }
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TService>(
- this Container container,
- Func<TService> instanceCreator) where TService : class
- {
- var creator =
- new PerWebRequestInstanceCreator<TService>(instanceCreator);
- container.Register<TService>(creator.GetInstance);
- }
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TConcrete>(this Container container)
- where TConcrete : class
- {
- container.Register<TConcrete>();
- container.ExpressionBuilt += (sender, e) =>
- {
- if (e.RegisteredServiceType == typeof(TConcrete))
- {
- var transientInstanceCreator = Expression.Lambda<Func<TConcrete>>(
- e.Expression, new ParameterExpression[0]).Compile();
- var creator = new PerWebRequestInstanceCreator<TConcrete>(
- transientInstanceCreator);
- e.Expression = Expression.Call(Expression.Constant(creator),
- creator.GetType().GetMethod(“GetInstance”));
- }
- };
- }
- [DebuggerStepThrough]
- public static void DisposeInstance<TService>() where TService : class
- {
- object key = typeof(PerWebRequestInstanceCreator<TService>);
- var instance = HttpContext.Current.Items[key] as IDisposable;
- if (instance != null)
- {
- instance.Dispose();
- }
- }
- private sealed class PerWebRequestInstanceCreator<T> where T : class
- {
- private readonly Func<T> instanceCreator;
- internal PerWebRequestInstanceCreator(Func<T> instanceCreator)
- {
- this.instanceCreator = instanceCreator;
- }
- [DebuggerStepThrough]
- public T GetInstance()
- {
- var context = HttpContext.Current;
- if (context == null)
- {
- // No HttpContext: Let’s create a transient object.
- return this.instanceCreator();
- }
- object key = this.GetType();
- T instance = (T)context.Items[key];
- if (instance == null)
- {
- context.Items[key] = instance = this.instanceCreator();
- }
- return instance;
- }
- }
- }
2. Modify Global.asax – The class name will be MvcApplication in MVC Project
- #region “Dependency Injection”
- private static Container Container;
- public static T GetInstance<T>() where T : class
- {
- return Container.GetInstance<T>();
- }
- protected void RegisterDependency()
- {
- //Create a main containers
- var container = new Container();
- // 2. Configure the container (register)
- container.RegisterPerWebRequest<IUnitOfWork>(() => new UnitOfWork(new PosDataContext()));
- container.Register<ITableRepository, TableRepository>();
- container.Verify();
- Container = container;
- }
- #endregion
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RegisterGlobalFilters(GlobalFilters.Filters);
- RegisterRoutes(RouteTable.Routes);
- BundleTable.Bundles.RegisterTemplateBundles();
- RegisterDependency();
- }
- protected void Application_EndRequest(object src, EventArgs e)
- {
- ServiceStack.MiniProfiler.Profiler.Stop();
- SimpleInjectorPerWebRequestExtensions.DisposeInstance<IUnitOfWork>();
- }
3. Consume it from the controller – Call the container in the Global.asax to resolve the object (GetInstance function)
- public ActionResult Index()
- {
- ViewBag.Title = “Tables”;
- return View(MvcApplication.GetInstance<IUnitOfWork>().TableRepository.Get(e => e.Active));
- }