IoC:Castle Windsor和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 / IPrincipaldependency injection(DI)/控制反转(IoC)

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

现有Castle Windsor MVC配置

假设你有MVC和Castle Windsor设置类似于Castle Windsor MVC教程 ,添加IoC以获得Web API控制器以利用dependency injection非常简单, Mark Seemann的post (注意他解释了为什么不使用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的post中,您需要通过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/ public IEnumerable Get() { return TestService.GetSomething(); //return new string[] { "value1", "value2" }; } } 

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

mirajavora / WebAPISample


这是详细说明的post:

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