[ Log On ]

Dependency Injection - Unity

Posted by frennky on 5/4/2011 @ 9:39 PM in Web Development

Jedno od glavnih poboljšanja koje nam MVC 3 donsi jeste bolja integracija sa IoC/DI kontejnerima. U ranijim verzijama MVC framework-a bilo je potrebno napraviti custom ControllerFactory. Međutim, postoji veliki broj IoC framework-a tako da je prirodnije da se komunikacija sa MVC framework-om odvija preko nekog interfejsa.

Za tu svrhu postoji jedan vrlo jednostavan interfejs - IDependencyResolver:

public interface IDepndencyResolver
{
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

I upravo implementacije ovog interfejsa treba da delegiraju zahteve za tipovima konkretnom IoC kontejneru.

UnityDependencyResolver:

public class UnityDependencyResolver : IDependencyResolver
{
    private readonly IUnityContainer container;

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

    public object GetService(Type serviceType)
    {
        try
        {
            return this.container.Resolve(serviceType);
        }
        catch
        {
            return null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return this.container.ResolveAll(serviceType);
        }
        catch
        {
            return new List<object>();
        }
    }
}

Ovde treba obratiti pažnju na to da ukoliko GetService nije u mogućnosti da vrati servis, treba da vrati null. I slično, ukoliko GetServices ne može da vrati servise treba da vrati praznu kolekciju. Ovo je važno jer ukoliko dođe do izuzetka on će biti vraćen korisniku kao run-time greška.

Nakon sto smo implementirali IDependencyResolver interfejs, potrebno je napuniti IoC kontejner:

protected void Application_Start()
{
    RegisterDependencyResolver();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

private void RegisterDependencyResolver()
{
    var container = new UnityContainer()
                        .RegisterType<IRepository, ConcreteRepository>()
                        .RegisterType<IService, ConcreteService>();
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}