2011-04-23

ASP.NET MVC and Unity

,

What is Unity?

The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection. Dependency injection is used to create loosely coupled applications. These kind of applications are easier to maintain and easier to test.

What do we want to achieve?

We want to make our controllers loosely coupled and break any hard dependencies it has. Every object/resource that our controller needs, has to be automatically populated and correctly initiated by Unity.

The Asp.net mvc application

This is the HomeController that we have in our application.

    public class HomeController : Controller
    {
        ITitleRepository _titleRepository = null;

        public HomeController()
        {
            _titleRepository = new TitleRepository();
        }

        //
        // GET: /Home/
        public ActionResult Index()
        {
            ViewBag.Title = _titleRepository.GetTitle("Index");

            return View();
        }
    }

As you can see, it uses a TitleRepository. This repository is used to determine which title has to be rendered on a specific page.  

            _titleRepository = new TitleRepository();

This is the line that we want to remove. With this, we make a hard dependency between our HomeController and the TitleRepository.

    public interface ITitleRepository
    {
        string GetTitle(String page);
    }

    public class TitleRepository : MVCWebsite.Repository.ITitleRepository
    {
        public String GetTitle(String page)
        {
            return String.Format(" This is a Title for the page: {0}", page);
        }
    }

 

Using Unity

Adding references

Add the Microsoft.Practices.Unity dll to you project. Unity can be found at http://unity.codeplex.com/.

Creating a custom LifetimeManager

When you register a type with Unity, you can also specify a lifetime of this type. If you don’t specify a lifetime, Unity will create a new instance of that type each time that the type is requested. In an Asp.Net application, we can make the LifetimeManager cache or store the created objects in the HttpContext HttpSession or HttpApplication. In my case, i want a singleton per request.

    public class HttpContextLifetimeManager<T> : LifetimeManager
    {
        public override void SetValue(object newValue)
        {
            HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
        }

        public override object GetValue()
        {
            return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
        }

        public override void RemoveValue()
        {
            HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
        }  
    }

Creating the UnityContainer

Next in line is the creation of a UnityContainer. This container will be used to resolve certain types. In order to work, we have to register these types. In our case, we our going to register the ITitleRepository type with the TitleRepository type. This will mean that if we ask the container to resolve the ITitleRepository, it will return a TitleRepository object. As you see, i pass the HttpContextLifetimeManager as parameter.

public class UnityConfigurator
{
    public static IUnityContainer GetContainer()
    {
        IUnityContainer container = new UnityContainer();

        container.RegisterType<ITitleRepository, TitleRepository>(new HttpContextLifetimeManager<ITitleRepository>());

        return container;
    }
}

Now we are registering our type hardcoded. It is also possible doing this in the config file.

Creating a Controller Factory

We need to create a custom Controller factory to replace the default factory that is used by the MVC framework. Our factory accepts a IUnityContainer as parameter. This container contains all the types we registered.

We only need to override the GetControllerInstance method. In this method we have to use the container to create an instance of the requested controller. This way, Unity will automatically resolve the requested types for this controller. In our case: ITitleRepository.

    public class UnityControllerFactory : DefaultControllerFactory
    {
        IUnityContainer container = null;

        public UnityControllerFactory(IUnityContainer container)
        {
            this.container = container;
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            IController result = null;

            if (null != controllerType)
            {
                result = container.Resolve(controllerType) as IController;
            }

            return result;
        }
    }


Now we have to tell the MVC framework to use the UnityControllerFactory as it’s default controller factory. This is done best in the global.asax, in the Application_Start method.

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(UnityConfigurator.GetContainer()));
}

 

Breaking the dependency

Now we have to modify our HomeController. We change it’s constructor to accept an object of the ITitleRepository type.

    public class HomeController : Controller
    {
        ITitleRepository _titleRepository = null;

        public HomeController(ITitleRepository titleRepository)
        {
            _titleRepository = titleRepository;
        }

        //
        // GET: /Home/
        public ActionResult Index()
        {
            ViewBag.Title = _titleRepository.GetTitle("Index");

            return View();
        }
    }

The result

When we go to the index of the HomeController, our UnityControllerFactory comes in action and Untity will inject the TitleRepository in the constructor of the HomeController.

When i want to use another implementation of the ITitleRepository, i only have to change the GetContainer method of the UnityConfigurator and the HomeController will automatically be injected with the new implementation.

    public class TitleRepository2 : MVCWebsite.Repository.ITitleRepository
    {
        public string GetTitle(String page)
        {
            return String.Format("{0} is the Title for this page!", page.ToUpper());
        }
    }

public class UnityConfigurator
{
    public static IUnityContainer GetContainer()
    {
        IUnityContainer container = new UnityContainer();

        container.RegisterType<ITitleRepository, TitleRepository2>(new HttpContextLifetimeManager<ITitleRepository>());

        return container;
    }
}

26 comments:

  1. How does HomeController know that what it is calling ? (TitleRepository2 or TitleRepository1 methods ? )

    What if i need methods from both classes ?

    Please explain.

    ReplyDelete
  2. Cats are one of the most popular and companions. Those that haven’t owned a cat before should read the following article. Continue reading for some advice on how to raise a cat.
    86620000 |

    beatsbydrecybermonday |

    dapoxetinebuynow |

    fioricetdirect2k |

    firstantidepressant |

    jsntcj |

    youngsmhs |

    michaelkorswatchhandbagssale |

    nike4freerun |

    pompeachaleurdevis |

    ReplyDelete
  3. your article very good and also your information very helpful visitors, thanks
    deposit pulsa
    deposit via pulsa
    bonus deposit togel
    pokerv

    ReplyDelete
  4. I really love your website.. Excellent colors & theme. Did you develop this site yourself? Please reply back as I’m trying to create my own blog and would like to know where you got this from or what the theme is named. Many thanks!

    poker online indonesia

    agen domino online
    bonus poker online
    website domino

    ReplyDelete
  5. Mencari akan situs poker online yang pastinya gampang menang itu hanya ada di http://badutqq.bloggin-ads.com/12704567/memakai-tertulis-situs-poker-online-menggunakan-data-valid dan tentunya akan ada kemenangan serta keuntungan besar setiap harinya.

    ReplyDelete
  6. Kemenangan besar dan keuntungan besar yang bisa kalian dapatkan pada situs yang terpercaya di http://winbadutq.qowap.com/25914730/hal-penting-pada-saat-bermain-judi-bandarq-online pastinya akan bisa kalian dapatkan setiap harinya.

    ReplyDelete
  7. Mencoba bermain pada situs terpercaya di https://periodicos.ufpel.edu.br/ojs2/index.php/dissertatio/user/viewPublicProfile/237097 yang dimana pastinya akan bisa mendapatkan kemenangan dan juga keuntungan yang besar.

    ReplyDelete
  8. Kemenangan yang besar dan keuntungan yang besar itu hanya ada di badutqq https://writeablog.net/jdyuceqq/belajar-cepat-strategi-menang-di-situs-bandarq-terpercaya yang dimana pastinya ada nilai bonus yang akan bisa kalian dapatkan juga.

    ReplyDelete
  9. visitors who actually need help with this important concern. Your personal commitment
    come further formerly again as exactly the same nearly a lot often inside case
    Simply wanted to inform you that you have people like https://www.total4d3.com/

    Total4D adalah bandar judi dan Agen Togel Online terbesar dan terpercaya mulai dari angka jitu Togel Singapore,hongkong,sidney dan data info keluaran togel

    Agen Togel Online
    Togel Online
    Togel Singapore
    Bandar Togel Terpercaya

    ReplyDelete
  10. Kedudukan Judi Online Taruhan Uang Orang Indonesia http://martinadria92.blogpostie.com/13528168/kedudukan-judi-online-taruhan-uang-orang-indonesia yang terpercaya di badutqq online ini saja.

    ReplyDelete
  11. Watch ufc 242 live stream khabib vs poirier live stream online reddit mma stream tickets, weigh-ins, fight card, timings, betting ods many more.

    IDN Poker
    Jackpot Poker
    Poker Online

    ReplyDelete
  12. DEKAPOKER situs IDN Poker dengan Permainan game kartu yang lengkap seperti Judi poker online, dominoQQ, Capsa Susun, Ceme Online dan Ceme Keliling yang sangat di rekomendasikan untuk dimainkan menggunakan uang asli.

    ReplyDelete
  13. Alasan Banyak Bettor Bermain Di Posisi DominoQQ Online Terpercaya http://badut99.blogpostie.com/14115148/alasan-banyak-bettor-bermain-di-posisi-dominoqq-online-terpercaya yang tepatnya alasan itu hanya ada pada badutqq online saja.

    ReplyDelete
  14. Keunggulan Bermain BandarQ Online Yang Menyertakan Keuntungan http://babe99.blogpostie.com/14225586/keunggulan-bermain-bandarq-online-yang-menyertakan-keuntungan yang terbaik dan terpercaya di babeqq terpercaya ini saja.

    ReplyDelete
  15. Situs Judi Terbaik Indonesia Dengan 9 Permainan Judi Online Terbaik http://99babeqq.blogpostie.com/14272191/situs-judi-terbaik-indonesia-dengan-9-permainan-judi-online-terbaik yang paling terpercaya hanya di babeqq saja.

    ReplyDelete
  16. ARTIKELNYA SANGAT BAGUS DAN DAN SANGAT BERMANFAAT.....

    AYO GABUNG DI POKER899X.CO !
    AGEN POKER ONLINE TERPERCAYA DAN TERBAIK
    BANYAK BONUSNYA :
    BONUS NEW MEMBER 10.000 - 20.000
    BONUS REFERRAL 10%
    BONUS MINGGUAN 0.3 - 0.5 %
    BONUS NEXT DEPOSIT 5%
    BONUS BULANAN

    TUNGGU APA LAGI ? BURUAN BERGABUNG DI POKER899.VIP , AGEN JUDI POKER TERPERCAYA DAN AGEN RESMI POKER IDN , SIAP MELAYANI ANDA PECINTA POKER !
    DAN KAMI JUGA MENERIMA PEMBAYARAN VIA PULSA, OVO, DAN GO-PAY

    JANGAN TUNGGU LAGI LANGSUNG DAFTAR DAN BUKTIAN ..!!

    POKER899X.CO !! RAIH KEMENANGANMU SEKARANG JUGA !!
    UNTUK INFO DAN PENDAFTARAN :
    LIVE CHAT : http://POKER899X.CO
    WHATSAPP : +855884660017
    LINE : POKER899


    BONUS NEW MEMBER TERBESAR
    AGEN POKER ONLINE TERPERCAYA
    BANDAR POKER ONLINE DEPOSIT VIA PULSA
    AGEN POKER ONLINE TERBESAR DI DUNIA




    ReplyDelete
  17. Berita Online
    Artikel Berita Olahraga Online Terpercaya dan Terakurat http://csliputanolahraga.blogpostie.com/15410850/artikel-berita-olahraga-online-terpercaya-dan-terakurat yang bisa kalian dapatkan informasi terbaiknya hanya disini saja.

    ReplyDelete