Nick
Nick

Reputation: 19664

MVC - Creating a Castle Windsor Controller Factory - No parameterless constructor defined for this object

I am introducing DI into my MS MVC application and I am having trouble getting the controllers instantiated from within my custom Controller Factory. It seems that the overridden "GetControllerInstance" is not being called.

Can someone tell me what I am missing?

My Controller Factory:

public class WindsorControllerFactory : DefaultControllerFactory
{
    public WindsorControllerFactory()
    {
        var controllerTypes = from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
                              where typeof (IController).IsAssignableFrom(t)
                              select t;
        foreach (Type controllerType in controllerTypes)
        {
            ApplicationContainer.Container.AddComponentLifeStyle(controllerType.FullName, controllerType,
                                                                 LifestyleType.Transient);
        }
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        if(controllerType !=null)
        {
            return (IController) ApplicationContainer.Container.Resolve(controllerType);
        }
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

}

Application_Start:

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());
    }

The controller factory is instantiated and but it would seem that it is not used to resolve the Controller. I placed a breakpoint on 'GetControllerInstance' but it is never hit.

The result is No parameterless constructor defined for this object. exception thrown

update:

I changed the GetControllerInstance to this:

 private WindsorContainer _container;

    public WindsorControllerFactory(WindsorContainer container)
    {
        _container = container;
        _container.Register(AllTypes.Of<IController>().FromAssembly(
      typeof(BaseFactoryController).Assembly).Configure(
          c => c.Named(c.Implementation.Name.ToLowerInvariant()).LifeStyle.Transient));
    }

Now I have to ignore null controllerType ?! If this is not commented:

//base.GetControllerInstance(requestContext, controllerType);

It begins to treat my .js files as a controller. Which throws httpException

protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return null;
        }
        //base.GetControllerInstance(requestContext, controllerType);
        return (IController) _container.Resolve(controllerType);
    }  

Upvotes: 1

Views: 2957

Answers (2)

Matthew Abbott
Matthew Abbott

Reputation: 61589

The other issue you may have is that this call:

AppDomain.CurrentDomain.GetAssemblies()

...won't retrieve all of the available controllers if the assemblies haven't actually been loaded into the AppDomain. The AppDomain loads assemblies when the are required, so if you haven't explicitly called them in code, they won't be loaded.

Upvotes: 0

Mauricio Scheffer
Mauricio Scheffer

Reputation: 99730

See creating WindsorContainer results in type conversion error (not quite the same question, but it's the same answer nevertheless)

Upvotes: 1

Related Questions