c# - Umbraco MVC 与 CaSTLe Windsor

标签 c# asp.net-mvc castle-windsor umbraco

有人有任何示例代码可以让 Umbraco MVC 与 CaSTLe Windsor 依赖注入(inject)框架一起工作吗?我遇到的问题是让我的表面 Controller 使用可注入(inject)的参数化构造函数。我知道我做错了什么,但不确定是什么。

我在这里遵循了(非 Umbraco)教程 - http://docs.castleproject.org/Windsor.Windsor-tutorial-part-four-putting-it-all-together.ashx - 这基本上意味着在 App_Start 上我正在运行这段代码:

var container = new WindsorContainer().Install(FromAssembly.This());
var controllerFactory = new MyCustomControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

MyCustomControllerFactory 的代码如下。

此外,我的 IWindsorInstaller 实现包含以下内容:

container.Register(Classes.FromThisAssembly()
    .BasedOn<SurfaceController>()
    .LifestyleTransient());

我得到的异常是“没有找到支持服务 Umbraco.Web.Mvc.RenderMvcController 的组件”,当我调用带有参数化的表面 Controller 时,由下面的 GetControllerInstance 方法抛出构造函数:

public class TestSurfaceController : SurfaceController
{
    public TestSurfaceController(INameService nameService)
    {
        ....
    }
}

如果有人有一些可用的示例代码,我将不胜感激。我之前已经将 Ninject 与 Umbraco 连接起来,没有遇到任何问题,但在这个项目中,我与 CaSTLe Windsor 联系在一起,很快就无处可去!提前致谢。

MyCustomControllerFactory.cs:

public class MyCustomControllerFactory : DefaultControllerFactory
{
    private readonly IKernel kernel;

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

最佳答案

我相信你的问题在这里:

ControllerBuilder.Current.SetControllerFactory(controllerFactory);

这将替换所有 Controller 的 Controller 工厂,包括 RenderMVCController,而 CaSTLe 找不到该类型的匹配组件。

诀窍是使用 FilteredControllerFactoryResolver,它让 Umbraco 根据您提供的一些标准(在这种情况下,您的容器是否可以解析 Controller 类型)决定使用哪个 Controller 。组合不像直接 MVC 应用程序(恕我直言)那样干净,但它可以工作。

这是一个实现 IFilteredControllerFactory 接口(interface)的过滤 Controller 的 (Umbraco 7.x) 示例:

public class FilteredControllerFactory : ControllerFactory, IFilteredControllerFactory
{
    public bool CanHandle(RequestContext request)
    {
        Type controllerType = GetControllerType(request, request.RouteData.Values["controller"].ToString());
        return ApplicationStartup.Container.Kernel.HasComponent(controllerType);
    }
}

以及设置组合的相应代码(使用 ApplicationEventHandler ):

public class ApplicationStartup : ApplicationEventHandler
{
    internal static IWindsorContainer Container;

    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        base.ApplicationStarting(umbracoApplication, applicationContext);

        Container = new WindsorContainer()
            .Install(Configuration.FromAppConfig())
            .Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());

        FilteredControllerFactoriesResolver.Current.InsertType<FilteredControllerFactory>(0);
    }
}

这种方法应该适用于路由劫持和表面 Controller 。

最后,请注意,如果您还想支持注入(inject) API Controller ,则需要单独连接。例如:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new CompositionRoot(Container.Kernel))

其中 CompositionRoot 是您自己的 Windsor 组合根类。

要点 here也可能有用。

关于c# - Umbraco MVC 与 CaSTLe Windsor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21835555/

相关文章:

c# - 使用 Exchange Web 服务 API 提取 Exchange 2007 公共(public)日历约会

c# - Flutter中 'Future<dynamic>'的实例

c# - 在 CaSTLe Windsor 中调用 ResolveAll 时的顺序

asp.net-mvc - Multi-Tenancy w/NHibernate+CaSTLe Windsor(单个应用程序,多个数据库)

c# - 将窗口置于前台的问题

c# - 创建 Windows 服务来运行 Visual Studio 解决方案

asp.net-mvc - WebForms 3.5 和 MVC 4.0 的跨子域身份验证问题

caSTLe-windsor - 在为下游依赖项提供值的同时解决依赖项

C# 单例实例永远不会为空

javascript - 从命令行触发 ASP.Net MVC 捆绑