温莎城堡ApiController厂实施的ASP.NET Web API [英] Castle Windsor ApiController Factory implementation for ASP.NET Web API

查看:121
本文介绍了温莎城堡ApiController厂实施的ASP.NET Web API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是可能使用DependancyResolver和MVC注册温莎城堡,但由于 http://stackoverflow.com描述的问题/ A /十三万九千三百九十二分之四百八十八万九千二百二十二我们坚持我们的MVC项目实施WindsorControllerFactory方法。

然而,它看起来像ApiControllers使用一些其他类型的工厂,因为温莎城堡是无法注入的依赖关系。

有没有人想出了如何使用温莎城堡与的ASP.NET Web API和MVC不使用DependencyResolver?


解决方案

由于Critiano的职位和一些搜索上线我设法得到它在这里工作是在code为别人有这个问题。我已经fgot它MVC3和ASP.NET Web API测试版的工作,但我认为,同样的解决方案应MVC4工作。

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

 公共类WindsorHttpControllerFactory:IHttpControllerFactory
{
    私人只读的iKernel内核;
    私人只读HttpConfiguration配置;    公共WindsorHttpControllerFactory(内核的iKernel,HttpConfiguration配置)
    {
        this.kernel =内核;
        this.configuration =配置;
    }    公共IHttpController CreateController(HttpControllerContext controllerContext,串controllerName)
    {
        如果(controllerName == NULL)
        {
            抛出新的HttpException(404的String.Format(以下简称控制器路径{0}可能不会被发现。controllerContext.Request.RequestUri.AbsolutePath));
        }        VAR控制器= kernel.Resolve< IHttpController>(controllerName);
        controllerContext.Controller =控制器;
        controllerContext.ControllerDescriptor =新HttpControllerDescriptor(配置,controllerName,controller.GetType());        返回controllerContext.Controller;
    }    公共无效ReleaseController(IHttpController控制器)
    {
        kernel.ReleaseComponent(控制器);
    }
}

最棘手的部分是登记似乎涉及注册一大堆其他的东西。这是我结束了。

<$p$p><$c$c>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&LT; HttpConfiguration&GT;()实例(配置));//注册所有API控制器
container.Register(AllTypes.FromAssembly(assemblyToRegister)
                            .BasedOn&LT; IHttpController&GT;()
                            .Configure(注册=方式&gt;。registration.Named(registration.ServiceType.Name.ToLower()更换(控制器,))LifeStyle.Transient));//注册WindsorHttpControllerFactory与服务解析
GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof运算(IHttpControllerFactory),container.Resolve&LT; IHttpControllerFactory&GT;());

我要创建我自己的实现,你可以使用一个存根版本像波纹管的ILogger的。

 公共类MyLogger:System.Web.Http.Common.ILogger
{
    公共无效LogException(串类别,级别的TraceLevel,例外的例外)
    {
        //这里如做一些记录。你可以使用log4net的
    }    公共无效日志(串类别,级别的TraceLevel,Func键&LT;串GT; messageCallback)
    {
        //这里如做一些记录。你可以使用log4net的
    }
}

I know it's possible to use DependancyResolver and register Castle Windsor with MVC but due to the issues described in http://stackoverflow.com/a/4889222/139392 we have stuck to the WindsorControllerFactory method of implementation on our MVC projects.

However it looks like the ApiControllers are using some other kind of factory as Castle Windsor is unable to inject the dependencies.

Has anyone figured out how to use Castle Windsor with ASP.NET Web API and MVC without using the DependencyResolver?

解决方案

Thanks to Critiano's post and some searching on-line I managed to get it to work here's the code for anyone else having this issue. I've fgot it working with MVC3 and ASP.NET Web Api Beta but I think the same solution should work for MVC4.

Firstly I created a WindsorHttpControllerFactory as the ApiControllers use a different factory than the MVC ones.

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

The tricky part was registration it seems to involved registering a whole bunch of other stuff. This is what I ended up with.

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

I had to create my own implementation of an ILogger you could use a stub version like bellow.

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
    }
}

这篇关于温莎城堡ApiController厂实施的ASP.NET Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆