2013-11-02 26 views
6

Sto provando ad installare Castle Windsor per la prima volta e ho qualche problema con esso. Ho tre progetti in mia soluzione:Setup Castle Windsor in MVC

  • dominio
  • DAL
  • Web

I servizi si trovano in DAL. Tutti ereditano da IService. (UserService strumenti IUserService, IUserService strumenti IService). L'applicazione Web è un'applicazione MVC 5. Tutti i controller ereditano da BaseController.

ho usato this post per aiutarmi messa a punto di Windsor, ma continuo a ricevere l'eccezione:

Un'eccezione di tipo 'Castle.MicroKernel.ComponentNotFoundException' si è verificato in Castle.Windsor.dll, ma non è stata gestita in user codice

Ulteriori informazioni: Nessun componente per supportare il servizio Solution.Web.Controllers.HomeController è stato trovato

la cosa strana è che il percorso per il cont il rullo è corretto

Qui di seguito è il mio codice per la configurazione:

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() 
     ); 
    } 
} 

E nel 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); 
    } 
} 

Qualsiasi aiuto o di orientamento nella giusta direzione è molto apprezzato!

risposta

9

L'ho fatto funzionare. Il problema era che i miei servizi non venivano registrati. Ho cambiato ServiceInstaller e la registrazione 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); 
} 
+0

Cool contenta che ora funzioni. Hai finito per dover cambiare la registrazione del controller? – greyalien007

+0

No, la registrazione del controller era corretta. Grazie ancora per i suggerimenti e la spiegazione! – Thijs

11

Sto assumendo che soffia qui:

return (IController)kernel.Resolve(controllerType); 

quello che stai chiedendo castello da fare qui in inglese è "dammi il componente che implementa un servizio definito da controllerType".

Il problema si presenta nella registrazione dei controller.

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

In questo blocco si indica il castello di registrare tutti i tipi che implementano BaseController ei servizi che stanno esponendo è anche BaseController.

Quindi il castello è alla ricerca di un componente che soddisfi il servizio HomeController e non riesca a trovare nulla perché l'unico servizio che hai è BaseController.

farla breve, se si rimuove

.WithServices(typeof(BaseController)) 

Castello assumeremo che ogni controller è un servizio e poi si può chiedere per i componenti che implementano il controller nel modo desiderato.

Come nota a parte, per chiarezza cambierei Types.FromThisAssembly() in Classes.FromThisAssembly() perché stai cercando solo le classi, non stompe/classi/interfacce, ecc.

+0

Ho apportato le modifiche suggerite ma continuo a ricevere lo stesso errore. Grazie per la spiegazione dettagliata di Castle :) – Thijs

Problemi correlati