No component for supporting the service System.Web.Mvc.IControllerFactory was found
Asked Answered
U

2

3

I have an issue in Castle Windsor. Please help me! I'm using Castle Windsor 3.2.0.0, .Net 4.0 and Mvc 3.0.0.0

Thank you so much!

Issue: No component for supporting the service Mvc IControllerFactory was found There is some code here.

public class WindsorDependencyResolver : IDependencyResolver
{
   private readonly IWindsorContainer _container;
   public WindsorDependencyResolver(IWindsorContainer container)
   {
       this._container = container;
   }

   public object GetService(Type serviceType)
   {
       return _container.Resolve(serviceType);
   }

   public IEnumerable<object> GetServices(Type serviceType)
   {
       return _container.ResolveAll(serviceType).Cast<object>();
       //return _container.ResolveAll<object>(serviceType);
   }
}

//Castle Windsor register
protected void Application_Start()
{
var container = new WindsorContainer();

container.AddFacility<TypedFactoryFacility>()
    .Register(Component.For<IServiceFactory>().AsFactory().LifeStyle.Transient);

        //Do register the service/type to container
container.Register(
  Types.FromThisAssembly()
  .BasedOn(typeof(Controller))
  .WithService.Self().LifestyleTransient());

container.Register(
  Component.For<IRepository>()
  .ImplementedBy<GenericRepository>().DependsOn(Dependency.OnValue("context", "ProjectContext"))
  .LifeStyle.PerWebRequest);

container.Register(
  Types.FromAssembly(Assembly.GetAssembly(typeof(IUserService)))
  .BasedOn(typeof(ServiceBase))
  .WithService.DefaultInterfaces().LifestylePerWebRequest());

DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
}
Upstage answered 2/7, 2013 at 6:35 Comment(0)
H
1

Agreed with Cristiano - here's how I did it, but it was a mix of both:

public class ContainerHostDependencyResolver : IDependencyResolver
{
    private static readonly IServiceLocator Locator = new ServiceLocator();
    private readonly IDependencyResolver _defaultResolver;
    private static readonly Type ControllerFactoryType = typeof (IControllerFactory);

    public ContainerHostDependencyResolver(IDependencyResolver defaultResolver)
    {
        _defaultResolver = defaultResolver;
    }

    public object GetService(Type serviceType)
    {
        if (ControllerFactoryType.IsAssignableFrom(serviceType))
            return Locator.Resolve(serviceType);

        return _defaultResolver.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _defaultResolver.GetServices(serviceType);
    }
}

    protected void Application_Start()
    {
        DependencyResolver.SetResolver(new ContainerHostDependencyResolver(DependencyResolver.Current));
    }

EDIT #1: This is a safer more straightforward approach that's doing what Cristiano's tutorial link is calling for. In my case, I have Windsor wrapped behind our own their called ContainerHost/ServiceLocator.

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ControllerBuilder.Current.SetControllerFactory(new ContainerHostControllerFactory());
    }
}

public class ContainerHostControllerFactory : DefaultControllerFactory
{
    private static readonly IServiceLocator Locator = new ServiceLocator();

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        return Locator.Resolve<IController>(controllerName + "Controller");
    }

    public override void ReleaseController(IController controller)
    {
        Locator.Release(controller);
    }
}
Hardpan answered 2/7, 2013 at 17:34 Comment(2)
Yuor choice... but DependencyResolver w/ windsor may lead to memory leak/zombie objects due to missing releasing hook...Curve
Cristiano is right actually. a fairly well known gap in IDependencyResolve is the lack of a Release method. In my case I didn't really care because my ControllerFactory implement is registered as a singleton and I'm implementing Release there. A safer more straight forward approach is to implement IControllerFactory and register it with MVC as the tutorial link he provided demonstrates. I'm going to post another answer with my code above revised. Cristiano deserves credit for this one IMO :)Hardpan
C
4

Stay away from DependencyResolver... use ControllerFactory instead.

Have a look to the tutorial

Curve answered 2/7, 2013 at 7:22 Comment(2)
Agreed - here's how I did it, but it was a mix of both:Hardpan
updated link: github.com/castleproject/Windsor/blob/master/docs/…Lynxeyed
H
1

Agreed with Cristiano - here's how I did it, but it was a mix of both:

public class ContainerHostDependencyResolver : IDependencyResolver
{
    private static readonly IServiceLocator Locator = new ServiceLocator();
    private readonly IDependencyResolver _defaultResolver;
    private static readonly Type ControllerFactoryType = typeof (IControllerFactory);

    public ContainerHostDependencyResolver(IDependencyResolver defaultResolver)
    {
        _defaultResolver = defaultResolver;
    }

    public object GetService(Type serviceType)
    {
        if (ControllerFactoryType.IsAssignableFrom(serviceType))
            return Locator.Resolve(serviceType);

        return _defaultResolver.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _defaultResolver.GetServices(serviceType);
    }
}

    protected void Application_Start()
    {
        DependencyResolver.SetResolver(new ContainerHostDependencyResolver(DependencyResolver.Current));
    }

EDIT #1: This is a safer more straightforward approach that's doing what Cristiano's tutorial link is calling for. In my case, I have Windsor wrapped behind our own their called ContainerHost/ServiceLocator.

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ControllerBuilder.Current.SetControllerFactory(new ContainerHostControllerFactory());
    }
}

public class ContainerHostControllerFactory : DefaultControllerFactory
{
    private static readonly IServiceLocator Locator = new ServiceLocator();

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        return Locator.Resolve<IController>(controllerName + "Controller");
    }

    public override void ReleaseController(IController controller)
    {
        Locator.Release(controller);
    }
}
Hardpan answered 2/7, 2013 at 17:34 Comment(2)
Yuor choice... but DependencyResolver w/ windsor may lead to memory leak/zombie objects due to missing releasing hook...Curve
Cristiano is right actually. a fairly well known gap in IDependencyResolve is the lack of a Release method. In my case I didn't really care because my ControllerFactory implement is registered as a singleton and I'm implementing Release there. A safer more straight forward approach is to implement IControllerFactory and register it with MVC as the tutorial link he provided demonstrates. I'm going to post another answer with my code above revised. Cristiano deserves credit for this one IMO :)Hardpan

© 2022 - 2024 — McMap. All rights reserved.