c# - ASP.NET Web API 的 CaSTLe Windsor ApiController Factory 实现

标签 c# asp.net asp.net-mvc-3 castle-windsor asp.net-web-api

我知道可以使用 DependencyResolver 并将 CaSTLe Windsor 注册到 MVC,但由于 https://stackoverflow.com/a/4889222/139392 中描述的问题我们在 MVC 项目中坚持使用 WindsorControllerFactory 实现方法。

但是看起来 ApiControllers 正在使用某种其他类型的工厂,因为 CaSTLe Windsor 无法注入(inject)依赖项。

有没有人想出如何在不使用 DependencyResolver 的情况下将 CaSTLe Windsor 与 ASP.NET Web API 和 MVC 一起使用?

最佳答案

多亏了 Critiano 的帖子和一些在线搜索,我设法让它工作,这里是其他遇到此问题的人的代码。我已经知道它可以与 MVC3 和 ASP.NET Web Api Beta 一起使用,但我认为相同的解决方案应该适用于 MVC4。

首先,我创建了一个 WindsorHttpControllerFactory,因为 ApiControllers 使用与 MVC 不同的工厂。

public class WindsorHttpControllerFactory : IHttpControllerFactory
{
    private readonly IKernel kernel;
    private readonly HttpConfiguration configuration;

    public WindsorHttpControllerFactory(IKernel kernel, HttpConfiguration configuration)
    {
        this.kernel = kernel;
        this.configuration = configuration;
    }

    public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
    {
        if (controllerName == null)
        {
            throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", controllerContext.Request.RequestUri.AbsolutePath));
        }

        var controller = kernel.Resolve<IHttpController>(controllerName);
        controllerContext.Controller = controller;
        controllerContext.ControllerDescriptor = new HttpControllerDescriptor(configuration, controllerName, controller.GetType());

        return controllerContext.Controller;
    }

    public void ReleaseController(IHttpController controller)
    {
        kernel.ReleaseComponent(controller);
    }
}

棘手的部分是注册,它似乎涉及注册一大堆其他东西。这就是我最终得到的。

container.Register(Component.For<IHttpControllerFactory>().ImplementedBy<WindsorHttpControllerFactory>().LifeStyle.Singleton);
container.Register(Component.For<System.Web.Http.Common.ILogger>().ImplementedBy<MyLogger>().LifeStyle.Singleton);
container.Register(Component.For<IFormatterSelector>().ImplementedBy<FormatterSelector>().LifeStyle.Singleton);
container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<DefaultHttpControllerActivator>().LifeStyle.Transient);
container.Register(Component.For<IHttpActionSelector>().ImplementedBy<ApiControllerActionSelector>().LifeStyle.Transient);
container.Register(Component.For<IActionValueBinder>().ImplementedBy<DefaultActionValueBinder>().LifeStyle.Transient);
container.Register(Component.For<IHttpActionInvoker>().ImplementedBy<ApiControllerActionInvoker>().LifeStyle.Transient);
container.Register(Component.For<System.Web.Http.Metadata.ModelMetadataProvider>().ImplementedBy<System.Web.Http.Metadata.Providers.CachedDataAnnotationsModelMetadataProvider>().LifeStyle.Transient);
container.Register(Component.For<HttpConfiguration>().Instance(configuration));

//Register all api controllers
container.Register(AllTypes.FromAssembly(assemblyToRegister)
                            .BasedOn<IHttpController>()
                            .Configure(registration => registration.Named(registration.ServiceType.Name.ToLower().Replace("controller", "")).LifeStyle.Transient));

//Register WindsorHttpControllerFactory with Service resolver
GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof(IHttpControllerFactory), container.Resolve<IHttpControllerFactory>());

我必须创建自己的 ILogger 实现,您可以使用如下所示的 stub 版本。

public class MyLogger : System.Web.Http.Common.ILogger
{
    public void LogException(string category, TraceLevel level, Exception exception)
    {
        // Do some logging here eg. you could use log4net
    }

    public void Log(string category, TraceLevel level, Func<string> messageCallback)
    {
        // Do some logging here eg. you could use log4net
    }
}

关于c# - ASP.NET Web API 的 CaSTLe Windsor ApiController Factory 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9557909/

相关文章:

c# - 使用 DataGridTemplateColumn.CellTemplate 并绑定(bind)到数据表时,DataGrid 中的重复列

c# - ASP.NET 标签显示 "System.Data"消息

asp.net - 添加并保留 "temporary"声明

asp.net - 在 _LogonPartial 中显示模型数据

c# - 鼠标停止移动后触发的 WPF 事件

c# - 解析 HTML 节点的正则表达式匹配失败

asp.net - asp.net中的SqlDependency

javascript - 返回 View MVC/Javascript/.NET Core 时出现问题

javascript - 在 MVC 中显示几行文本

asp.net-mvc-3 - 全局命名空间 + MVC3?