Setting Windsor Castle in MVC

I am trying to set up Castle Windsor for the first time and am having some problems with it. I have three projects in my solution:

  • Domain
  • DAL
  • Web

Facilities are located in DAL. All of them are inherited from IService . ( UserService implements IUserService , IUserService implements IService ). The web application is an MVC 5 application. All controllers are inherited from BaseController .

I used this post to help me configure Windsor, but I get an exception:

An exception like "Castle.MicroKernel.ComponentNotFoundException" occurred in Castle.Windsor.dll but was not handled in the user code

Additional information: a component to support the solution.Web.Controllers.HomeController service was not found

It is strange that the path for the controller is correct.

Below is my configuration code:

 public class WindsorControllerFactory : DefaultControllerFactory { private readonly IKernel kernel; public WindsorControllerFactory(IKernel kernel) { this.kernel = kernel; } public override void ReleaseController(IController controller) { kernel.ReleaseComponent(controller); } 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)); } return (IController)kernel.Resolve(controllerType); } } public class ControllersInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Classes.FromThisAssembly() .BasedOn(typeof(BaseController)) .LifestyleTransient()); } } public class ServiceInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Types.FromAssemblyContaining(typeof(IService).GetType()) .BasedOn<IService>().WithService.FromInterface() .LifestyleTransient() ); } } 

And in Global.asax:

 public class MvcApplication : System.Web.HttpApplication { private static IWindsorContainer container; protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // Setup Castle.Windsor IOC MvcApplication.BootstrapContainer(); } protected void Application_End() { container.Dispose(); } private static void BootstrapContainer() { container = new WindsorContainer().Install(FromAssembly.This()); container.Install(FromAssembly.Containing(typeof(IService).GetType())); var controllerFactory = new WindsorControllerFactory(container.Kernel); ControllerBuilder.Current.SetControllerFactory(controllerFactory); } } 

Any help or guidance in the right direction is appreciated!

+6
source share
2 answers

I have earned. Violently the problem was that my services were not registered. I changed ServiceInstaller and registration in Global.asax.

 public class ServiceInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromAssemblyContaining<BaseService>() .BasedOn(typeof(IService)) .WithService.AllInterfaces() .LifestyleTransient()); } } private static void BootstrapContainer() { container = new WindsorContainer(); container.Install(new ServiceInstaller()); container.Install(new ControllersInstaller()); var controllerFactory = new WindsorControllerFactory(container.Kernel); ControllerBuilder.Current.SetControllerFactory(controllerFactory); } 
+9
source

I guess this explodes here:

 return (IController)kernel.Resolve(controllerType); 

What you are asking the castle to do here in English is "give me a component that implements a service defined using the type of controller."

The problem occurs when registering your controllers.

 container.Register( Types.FromThisAssembly() .BasedOn(typeof(BaseController)) .WithServices(typeof(BaseController)) .LifestyleTransient()); 

In this block, you force the lock to register all your types that implement BaseController, and the services they expose are also BaseController.

So, the lock is looking for a component that satisfies the HomeController service and cannot find anything, because your only service is BaseController.

In short, if you delete

 .WithServices(typeof(BaseController)) 

The lock will assume that each of your controllers is a service, and then you can request components that implement your controller the way you want.

As a separate note, for clarity, I would change Types.FromThisAssembly () to Classes.FromThisAssembly (), because you are only looking for classes, not stucts / classes / interfaces, etc. that will scan types.

+11
source

Source: https://habr.com/ru/post/957252/


All Articles