2011-09-12 123 views
4

我使用的是Castle Windsor 3.0,它在我嘗試註冊控制器(我使用WCF工具和IoC作爲存儲庫/服務層)之前完美地工作。這裏是我的控制器安裝程序類:Castle Windsor 3.0和ASP.NET MVC Controllers

public class ControllersInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     RegisterAllBasedOnWithCustomComponentRegistration(container, typeof(IController), 
      typeof(HomeController).Assembly, 
      cr => cr.LifeStyle.Transient); 

    } 

    private void RegisterAllBasedOnWithCustomComponentRegistration(IWindsorContainer container, Type baseType, 
    Assembly assemblyWithImplementations, Func<ComponentRegistration, ComponentRegistration<object>> customComponentRegistrationCb) 
    { 
     container.Register(
      AllTypes.FromAssembly(assemblyWithImplementations) 
       .BasedOn(baseType) 
       .If(t => t.Name.EndsWith("Controller")) 
       .Configure(c => customComponentRegistrationCb(c))); 
    } 
} 

這裏是我的控制器廠:

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    private readonly IKernel _kernel; 

    public WindsorControllerFactory(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    public override void ReleaseController(IController controller) 
    { 
     _kernel.ReleaseComponent(controller); 
    } 

    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) 
    { 
     var controllerComponentName = controllerName + "Controller"; 
     return _kernel.Resolve<IController>(controllerComponentName); 
    } 
} 

從我的Global.asax我叫下一個方法:

InversionOfControl.InstallControllers(FromAssembly 。這個());

它位於另一個項目。並在那裏我做調用安裝代碼:

public static void InstallControllers(IWindsorInstaller install) 
    { 
     _container.Install(install); 
    } 

好像我做錯了什麼,我希望我是因爲它可能是一個「永遠不會再使用測試版awny」那一刻我。

我得到一個異常:支持服務System.Web.Mvc.IController的成分,不被發現 altough我可以看到在調試模式控制器被註冊在容器

+0

這一切都在那裏,在異常消息。看來你試圖解決你的控制器爲'IController'而不是它的實現類 –

+0

嗯,我要求它正確解析controllerName中的HomeController,而不是IController。可能是我問錯了,我不是嗎? –

回答

1

在這種情況下添加.WithServices(typeof運算(一個IController))和名稱的所有組件。

cr => cr.LifeStyle.Transient.Named(cr.Implementation.Name) 

和您的註冊應該是這樣的:

.Register(
AllTypes.FromAssembly(assemblyWithImplementations) 
     .BasedOn(baseType) 
     .WithServices(typeof(IController)) 
     .If(t => t.Name.EndsWith("Controller"))...) 
+0

除'WithService'部分是錯誤的,並且只會意外工作,因爲你指向你想要通過其名稱的特定組件,忽略它暴露的服務。 –

+0

是的,你是對的。在這種情況下,WindsorControllerFactory應該被重構爲Mark Seemann在下面提出的建議。 – isuruceanu

9

在你的ControllerFactory,你不應該解決IController而是具體的控制器類型。下面是一個典型溫莎基的ControllerFactory我總是用:

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    private readonly IWindsorContainer _container; 

    public WindsorControllerFactory(IWindsorContainer container) 
    { 
     _container = container; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     return (IController)_container.Resolve(controllerType); 
    } 

    public override void ReleaseController(IController controller) 
    { 
     _container.Release(controller); 
    } 
} 
+0

爲什麼匿名downvote? –

+0

這不是我,馬克 –

+1

對不起,而不是投票我不小心投票,我確認你的解決方案更優雅。 – isuruceanu