IoC Castle Windsor - No parameterless constructor defined for this object

百般思念 提交于 2019-12-07 02:48:48

问题


I'm getting the 'No parameterless constructor defined for this object' on my controller when the controller and its dependencies are being registered accordingly via (DI/IoC) pattern using Castle Windsor. Can someone take a look at the following and see my error because i can't see it.

Code for registration on global.asax

public class MyApplication : System.Web.HttpApplication
{ 
    public MvcApplication()
    {
        this.container = new WindsorContainer().Install(new DependencyInstaller());
    }
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),
        new WindsorActivator(this.container));
    }
}

My DI

public class DependencyInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<IDatabaseFactory>().ImplementedBy<DatabaseFactory>().LifeStyle.PerWebRequest,
            Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>().LifeStyle.PerWebRequest,
            Component.For<IMappingEngine>().ImplementedBy<MappingEngine>().UsingFactoryMethod(() => Mapper.Engine).LifeStyle.Singleton,
            Component.For<IFirmTasks>().ImplementedBy<FirmTasks>().LifeStyle.PerWebRequest,
            Classes.FromAssemblyContaining<PersonController>().BasedOn<IController>().LifestyleTransient(),
            Classes.FromThisAssembly().BasedOn<IHttpController>().LifestyleTransient(),
            Classes.FromAssemblyNamed("Core.Firm.Tasks").Where(type => type.Name.EndsWith("Tasks")).WithServiceAllInterfaces().LifestylePerWebRequest(),
            Classes.FromAssemblyNamed("Core.Firm.Repository")
                .Where(type => type.Name.EndsWith("Repository")).WithServiceAllInterfaces().LifestylePerWebRequest()
            );
    }
}

my controller

public class PersonController : Controller
{
    private IFirmTasks tasks;

    public PersonController(IFirmTasks tasks)
    {
        this.tasks = tasks;
    }

When I load the application the container loads fine with all dependencies resolved as per screen shot on debug.

Anyone out there got any idea's where my failings lie. Thanks in advance.


回答1:


When I load the application the container loads fine with all dependencies resolved as per screen shot on debug.

Yes, all your types are registered.

If you write var controller = container.Resolve<PersonController>(); in the Global.asax you should get an instance of your controller.

Your implementation is valid for Asp.Net WebApi and it works for System.Web.Http.ApiControllers only.

Your code does not work properly because your PersonController inherits System.Web.Mvc.Controller and System.Web.Mvc.DefaultControllerFactory is used. You can see it in the first picture.

You should write and inject your custom ControllerFactory in Global.asax in order to create Asp.Net MVC controllers.

    //Set the controller builder to use our custom controller factory
    var controllerFactory = new WindsorControllerFactory(container);
    ControllerBuilder.Current.SetControllerFactory(controllerFactory);

You can read more in this answer on another SO question.

Here is a default implementation of WindsorControllerFactory:

/// <summary>
/// Controller factory the class is to be used to eliminate hard-coded dependencies 
/// between controllers and other components
/// </summary>
public class ControllerFactory : DefaultControllerFactory
{
    private readonly IWindsorContainer container;

    public WindsorControllerFactory(IWindsorContainer container)
    {
        this.container = container;
    }

    public override void ReleaseController(IController controller)
    {
        container.Release(controller.GetType());
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return (IController)container.Resolve(controllerType);
    }
}


来源:https://stackoverflow.com/questions/21631323/ioc-castle-windsor-no-parameterless-constructor-defined-for-this-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!