Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle windsor 3.0 and ASP.NET MVC Controllers

I am using Castle Windsor 3.0 and it worked perfectly for me until I tried to register controllers (I used WCF facility and IoC for repository/service layer). Here is my controllers installer class:

public class ControllersInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        RegisterAllBasedOnWithCustomComponentRegistration(container, typeof(IController),
            typeof(HomeController).Assembly,
            cr => cr.LifeStyle.Transient);

    }

    private void RegisterAllBasedOnWithCustomComponentRegistration(IWindsorContainer container, Type baseType,
    Assembly assemblyWithImplementations, Func<ComponentRegistration, ComponentRegistration<object>> customComponentRegistrationCb)
    {
        container.Register(
            AllTypes.FromAssembly(assemblyWithImplementations)
                .BasedOn(baseType)
                .If(t => t.Name.EndsWith("Controller"))
                .Configure(c => customComponentRegistrationCb(c)));
    }
}

And here is my controller factory:

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IKernel _kernel;

    public WindsorControllerFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override void ReleaseController(IController controller)
    {
        _kernel.ReleaseComponent(controller);
    }

    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        var controllerComponentName = controllerName + "Controller";
        return _kernel.Resolve<IController>(controllerComponentName);
    }
}

From my global.asax I call the next method:

InversionOfControl.InstallControllers(FromAssembly.This());

which lies in an another project. And in there I do call the installation code:

    public static void InstallControllers(IWindsorInstaller install)
    {
        _container.Install(install);
    }

it seems like I am doing something wrong and I hope I am because it could be a "never use awny beta again" moment for me.

I get the next exception : No component for supporting the service System.Web.Mvc.IController was found altough I can see the controller in the debug mode being registered in the container

like image 651
Yurii Hohan Avatar asked Dec 27 '22 14:12

Yurii Hohan


2 Answers

In your ControllerFactory, you don't shouldn't Resolve IController but rather the concrete controller type. Here's a typical Windsor-base ControllerFactory I always use:

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IWindsorContainer _container;

    public WindsorControllerFactory(IWindsorContainer container)
    {
        _container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return (IController)_container.Resolve(controllerType);
    }

    public override void ReleaseController(IController controller)
    {
        _container.Release(controller);
    }
}
like image 60
Mark Seemann Avatar answered Jan 08 '23 23:01

Mark Seemann


In this case add .WithServices(typeof(IController)) and name all components.

cr => cr.LifeStyle.Transient.Named(cr.Implementation.Name)

and your registration should look like:

.Register(
AllTypes.FromAssembly(assemblyWithImplementations)
        .BasedOn(baseType)
        .WithServices(typeof(IController))
        .If(t => t.Name.EndsWith("Controller"))...)
like image 35
isuruceanu Avatar answered Jan 08 '23 23:01

isuruceanu