views:

102

answers:

2

I'm putting the unity container creation/setup in the global.asax. and making the container a static property on that class since i'm not sure how unity works or if the container needs to be kept alive and references elsewhere. What's the recommended location of unity initialization/configuration for mvc 2?

+1  A: 

You shouldn't need to keep an explicit reference around for the container. A container should wire up the requested object graph (Controllers in this case) and get out of the way.

Take a look at the container-specific implementations of IControllerFactory in MVCContrib.

That said, I like the WindsorControllerFactory a lot better than the UnityControllerFactory, but you could implement a UnityControllerFactory that uses the same pattern (Constructor Injection) as the WindsorControllerFactory.

If you imagine that we do that, your Global.asax should look like this:

var container = new UnityContainer();

// configure container

var controllerFactory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

controllerFactory holds a reference to the container, so you can let it go out of scope in Application_Start - it's going to stay around because the ControllerFactory stays around.

Mark Seemann
would this example be advisable for things besides just controller factories? I'm looking at how to wire up domain logic classes with their proper repositories (employee repository, Emailer repository, etc..)
Maslow
Yes. If it's ASP.NET MVC, they all need to go through the Controllers anyway. Let the container inject the Presentation layer services into the Controllers; the Domain Objects into the Presentation layer services; the Repositories into the Domain Objects, etc.
Mark Seemann
A: 

Here's how we did it:

public class UnityControllerFactory : DefaultControllerFactory
{
    private IUnityContainer container;

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

    public static void Configure()
    {
        IUnityContainer container = new UnityContainer();
        //...Register your types here

        ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return base.GetControllerInstance(requestContext, controllerType);
        }

        if (!typeof(IController).IsAssignableFrom(controllerType))
        {
            throw new ArgumentException("Type requested is not a controller", "controllerType");
        }

        return container.Resolve(controllerType) as IController;
    }
}

And then in global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        .... whatever you like
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        UnityControllerFactory.Configure();
    }
}
Jedidja
would this example be advisable for using unity for things besides just controllers?
Maslow
I believe so - as Mark said in his updated answer, you will always have access to the container. And Unity will happily build anything you throw at it :)
Jedidja
The controllers would, in theory, have a dependency on the repositories (or a service that uses the repositories) so everything will get built through Unity in the end.
Jedidja