【问题标题】:Castle windsor 3.0 and ASP.NET MVC ControllersCastle windsor 3.0 和 ASP.NET MVC 控制器
【发布时间】:2011-09-12 11:18:39
【问题描述】:

我正在使用 Castle Windsor 3.0,在我尝试注册控制器之前,它对我来说非常有效(我使用 WCF 设施和 IoC 作为存储库/服务层)。这是我的控制器安装程序类:

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.This());

位于另一个项目中。在那里我确实调用了安装代码:

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

似乎我做错了什么,我希望我是因为这对我来说可能是一个“永远不要再使用 awny beta”的时刻。

我得到下一个异常:没有找到支持服务 System.Web.Mvc.IController 的组件尽管我可以看到处于调试模式的控制器正在容器中注册

【问题讨论】:

  • 一切都在那里,在异常消息中。看来您正在尝试将您的控制器解析为 IController 而不是它的实现类
  • 好吧,我要求它准确解析控制器名称中的 HomeController,而不是 IController。可能我问错了吧?

标签: c# dependency-injection castle-windsor


【解决方案1】:

在您的 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);
    }
}

【讨论】:

  • 抱歉,我不小心投了反对票,而不是投票,我确认您的解决方案更优雅。
  • 感谢您的解释。这些事情发生了 - 没有难过的感觉:)
【解决方案2】:

在这种情况下,添加 .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"))...)

【讨论】:

  • 除了WithService 部分是错误的并且只能在偶然情况下起作用,因为您通过其名称指向您想要的特定组件,而忽略了它公开的服务。
  • 是的,你是对的。在这种情况下,WindsorControllerFactory 应该按照 Mark Seemann 下面的建议进行重构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多