R – Castle Windsor and IPrincipal

castle-windsor

Is is possible to inject IPrincipal using Castle Windsor into my asp.net mvc controller. This article by Scott Hanselman has code in the comments to do it with structure map, but I cannot figure out how to do it with Castle.

Update:

Here is what I ended up with for my controller factory. Note that most of the code is from Steve Sanderson's Pro ASP.NET MVC book with the addition of the code from the answers below.

public class WindsorControllerFactory : DefaultControllerFactory
{
    readonly WindsorContainer _container;
    // The constructor:
    // 1. Sets up a new IoC container
    // 2. Registers all components specified in web.config
    // 3. Registers IPrincipal
    // 4. Registers all controller types as components
    public WindsorControllerFactory()
    {
        // Instantiate a container, taking configuration from web.config
        _container = new WindsorContainer(
        new XmlInterpreter(new ConfigResource("castle"))
        );

        _container.AddFacility<FactorySupportFacility>();
        _container.Register(Component.For<IPrincipal>()
          .LifeStyle.PerWebRequest
          .UsingFactoryMethod(() => HttpContext.Current.User));

        // Also register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (var t in controllerTypes)
            _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
    }

    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)_container.Resolve(controllerType);
    }        
}

Best Answer

If you're using Windsor 2.0, there's no need to modify the ControllerFactory:

var container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IPrincipal>()
  .LifeStyle.PerWebRequest
  .UsingFactoryMethod(() => HttpContext.Current.User));
// your component registrations...

This is just a wrapper around the Factory facility configuration. If you're using a previous version (RC3) you can configure this with XML too.

Related Topic