Existing Castle Windsor MVC configuration
Assuming you have MVC and Castle Windsor setup similarly to the Castle Windsor MVC tutorial, adding IoC to get Web API controllers to utilize dependency injection is very simple with Mark Seemann's post (note that he explains why not to use IDependencyResolver).
From the Castle Windsor tutorial you should have something like this in 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()
snip
IWindsorContainer container = new WindsorContainer()
.Install(
new LoggerInstaller()
//...,
, new ControllersInstaller()
);
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
return container;
Required changes
From Mark Seemann's post you need to get into Web API's entry point (Composition Root) through the IHttpControllerActivator
. Here's his adapter implementation which you need.
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();
}
}
}
With the IHttpControllerActivator adapter and the MVC Castle Windsor container implementation, you just need to configure it in the Global.asax.cs
(or in BootStrapper if you used that). It has to be after the MVC initialization since the MVC initialization has all of the installers.
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));
}
Final Result:
The Web API controllers can use your injected dependencies the same as your MVC controllers.
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" };
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…