c# - 国际奥委会 : CaSTLe Windsor and WebAPI

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

我有一个使用 CaSTLe Windsor 的 MVC4 站点,我想向其添加一些 WebAPI 调用,因此我开始在互联网上进行一些挖掘。

现在我不知道 IoC 的来龙去脉;我遵循了如何在我的项目上设置温莎城堡的教程,将 IUnitOfWorkFactoryIApplicationService 作为公共(public)属性注入(inject)到基本 Controller 中,并根据需要注入(inject)一些其他接口(interface)在 Controller 构造函数中。它运行顺畅,所以我从来不需要用它做更多的事情。

我在阅读有关 WebAPI 的所有内容时,都被告知使用 CaSTLe Windsor 时 DI 将无法很好地工作,并谈论 IDependencyResolverIDependencyScope 的问题。有几种解决方法和实现方法可以解决这个问题,但我不清楚问题到底是什么。包含代码片段,但前提是您知道它们属于哪个类,以及它们是如何被调用的,不幸的是我不知道。此外,我在网上看到的所有示例都指的是一个独有的 WebAPI 项目,而不是明智地加入了几个 ApiController 的 MVC4 项目。我不知道这会如何影响,或者是否会影响任何东西。

为什么我在标准 Controller 上使用的功能不能在 API Controller 上使用?要让 WebAPI 调用和标准 Web 调用在同一个应用程序中工作,需要执行什么样的代码技巧?

最佳答案

现有的 CaSTLe Windsor MVC 配置

假设您有类似于 Castle Windsor MVC tutorial 的 MVC 和 CaSTLe Windsor 设置,使用 Mark Seemann's post 添加 IoC 以使 Web API Controller 利用依赖注入(inject)非常简单(注意他解释了为什么不使用 IDependencyResolver)

在 CaSTLe Windsor 教程中,您应该在 Global.asax.cs 中有类似的内容。

    private static IWindsorContainer container;

    protected void Application_Start()
    {
        //... MVC / Web API routing etc.
        BootStrapper bs = new BootStrapper();
        container = bs.ConfigureCastleWindsorMVC();
    }

BootStrapper.ConfigureCaSTLeWindsorMVC() 片段

        IWindsorContainer container = new WindsorContainer()
            .Install(
                new LoggerInstaller()
                //...,
                , new ControllersInstaller()
            );

        var controllerFactory = new WindsorControllerFactory(container.Kernel);
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);
        return container;

所需的更改

根据 Mark Seemann 的帖子,您需要进入 Web API 的 entry point (Composition Root)通过 IHttpControllerActivator。这是您需要的他的适配器实现。

public class WindsorCompositionRoot : IHttpControllerActivator
{
    private readonly IWindsorContainer container;

    public WindsorCompositionRoot(IWindsorContainer container)
    {
        this.container = container;
    }

    public IHttpController Create(HttpRequestMessage request,
        HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        var controller =
            (IHttpController)this.container.Resolve(controllerType);

        request.RegisterForDispose(
            new Release(() => this.container.Release(controller)));

        return controller;
    }

    private class Release : IDisposable
    {
        private readonly Action release;

        public Release(Action release) { this.release = release; }

        public void Dispose()
        {
            this.release();
        }
    }
}

有了 IHttpControllerActivator 适配器和 MVC CaSTLe Windsor 容器实现,您只需在 Global.asax.cs(或者如果您使用 BootStrapper)中配置它。它必须在 MVC 初始化之后,因为 MVC 初始化具有所有安装程序。

    private static IWindsorContainer container;

    protected void Application_Start()
    {
        // MVC / Web API routing etc.
        BootStrapper bs = new BootStrapper();
        container = bs.ConfigureCastleWindsorMVC();
        // Web API Castle Windsor ++ ADD THIS ++
        GlobalConfiguration.Configuration.Services.Replace(
            typeof(IHttpControllerActivator),
            new WindsorCompositionRoot(container));
    }

最终结果:

Web API Controller 可以像您的 MVC Controller 一样使用您注入(inject)的依赖项。

public class TestController : ApiController
{
    private readonly ITestService TestService;

    public TestController(ITestService testService)
    {
        this.TestService = testService;
    }

    // GET api/<controller>
    public IEnumerable<string> Get()
    {
        return TestService.GetSomething();
        //return new string[] { "value1", "value2" };
    }
}

关于c# - 国际奥委会 : CaSTLe Windsor and WebAPI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16154566/

相关文章:

c# - 如何在WPF中检测父对象的子对象的变化?

c# - 为什么这个简单的线程输出是正确的

asp.net-mvc - 使用 mvc 创建博客条目的快照/缩略图

c# - 如何在 ASP NET MVC 中使用负数而不是括号显示货币?

jquery - 如何使用 jquery 禁用按钮

asp.net-mvc-4 - ASP.NET MVC4 和 CodeFirst 中的一对多关系

c# - 命名空间和类具有相同的名称

c# - 获取代码隐藏以创建完整的 JS 部分

asp.net-mvc - 在 ASP.NET MVC3 中的 Post Action 中获取属性值(List<long>)

c# - 找不到动脉 SignalR/ping MVC 4