繁体   English   中英

IoC:Castle Windsor和WebAPI

[英]IoC: Castle Windsor and WebAPI

我有一个使用Castle Windsor的MVC4站点,我想添加一些WebAPI调用,所以我开始在互联网上挖掘一下。

现在我不知道IoC的来龙去脉; 我按照教程了解了如何在我的项目中设置Castle Windsor,将IUnitOfWorkFactoryIApplicationService注入基本控制器中的公共属性,以及控制器构造函数中需要的一些其他接口。 它游泳,所以我从来没有做过更多。

我正在WebAPI上读到的任何地方,我被告知DI使用Castle Windsor无法正常工作,谈论IDependencyResolverIDependencyScope 有几种解决方法和实现如何解决这个问题,但我不清楚的是究竟是什么问题。 包含代码片段,但假设您知道它们属于哪个类,以及如何调用它们,遗憾的是我没有。 另外,我在网上看到的所有例子都提到了一个独家的WebAPI项目,而不是一个明智地抛出几个ApiController的MVC4项目。我不知道这是怎样的,或者是否会影响到任何东西。

为什么我的标准控制器无法使用API​​控制器? 为了让WebAPI调用和标准Web调用在同一个应用程序中工作,需要做什么样的代码杂技?

要使用带有webapi的Windsor,请访问http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor/(BEH:fixed link)

阅读ASP.NET Web API中的Castle Windsor / DelegatingHandler / IPrincipal依赖注入(DI)/控制反转(IoC)

您可以在同一个应用程序中使用webapi和MVC控制器(我更喜欢将它保持独立)但路由和控制器工厂不同,您必须设置两个不同的配置并处理路由重叠...对于MVC和Windsor,您可以找到一个大

现有Castle Windsor MVC配置

假设你有类似于Castle Windsor MVC教程的 MVC和Castle Windsor设置,使用Mark Seemann的帖子 (注意他解释了为什么不使用IDependencyResolver) ,添加IoC以使Web API控制器利用依赖注入非常简单。

从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的帖子中,您需要通过IHttpControllerActivator进入Web API的入口点(Composition Root) 这是他需要的适配器实现。

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控制器可以使用与MVC控制器相同的注入依赖项。

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

以下示例项目给了我正在寻找的答案。 它使用Castle Windsor进行依赖注入。 我能够在同一个应用程序上使用MVC控制器和Web API控制器。

mirajavora / WebAPISample


这是详细说明的帖子:

ASP.NET Web API入门

首先,Iko声明您需要创建一个实现IHttpControllerActivator的类。

然后在Bootstrap()中的ContainerBootstrapper中添加以下内容:将默认值替换为实现的默认值:

 //This will help in creating Web api with Dependency injection
 GlobalConfiguration.Configuration.Services.Replace(
 typeof(IHttpControllerActivator),
 new WindsorCompositionRoot(container));

最后这里没有提到它,如果没有它你不应该在你在install()实现IWindsorInstaller服务中添加以下内容:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM