1

Following the standard MVC 5 tutorials for Windsor, I have created a WindsorControllerFactory with:

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
    if (controllerType == null)
    {
        throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
    }

    if (controllerType != null && kernel.HasComponent(controllerType))
        return (IController)kernel.Resolve(controllerType);
    return base.GetControllerInstance(requestContext, controllerType);
}

I also want to start using BetterCMS and I've gotten the right Nuget package and tried to initialize it in Global.asax:

__CmsHost = CmsContext.RegisterHost();

After that is called, when I inspect my ControllerBuilder.Current.GetDefaultControllerFactory(), I have the appropriate factory for BetterCMS.

But to use Windsor, I need to register my own controller factory:

var controllerFactory = new WindsorControllerFactory(__Container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

Of course, now I get an error when I try to access a BetterCMS controller - it doesn't recognize the controller it needs to build.

I've tried restricting the namespace of the container's registration of the controllers, but that doesn't change the result:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
        Classes.FromThisAssembly()
        .InNamespace("MyNamespace.Net.Web.Platform.Controllers", true)
        .LifestyleTransient());
}

I mean, it's not like Microsoft's SetControllerFactory is going to respect my Windsor container.

Short of creating a factory by composing the BetterCMS factory with my own, what can I do to get these two to play nice?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126

1 Answers1

0

You could use a decorator pattern so you don't have to compose them together.

public class ControllerFactoryDecorator : IControllerFactory
{
    public ControllerFactoryDecorator(
        IControllerFactory controllerFactory
        )
    {
        if (controllerFactory == null)
            throw new ArgumentNullException("controllerFactory");
        this.innerControllerFactory = controllerFactory;
    }

    private readonly IControllerFactory innerControllerFactory;

    // Implement IControllerFactory members and delegate each
    // call to the innerControllerFactory if it doesn't apply here.
}

And then just wrap whatever existing IControllerFactory there is.

// Setup the Controller Factory with a decorator
var currentFactory = ControllerBuilder.Current.GetControllerFactory();
ControllerBuilder.Current.SetControllerFactory(
    new ControllerFactoryDecorator(currentFactory));

See a complete example here.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212