IoC: Замок Виндзор и WebAPI
У меня есть сайт MVC4 с использованием Castle Windsor, к которому я хочу добавить некоторые вызовы WebAPI, поэтому я начинаю немного копаться в интерфейсах.
Теперь я не знаю входы и выходы IoC; Я последовал за учебником о том, как настроить Castle Windsor в моем проекте, введя IUnitOfWorkFactory
и IApplicationService
в качестве общедоступных свойств в базовом контроллере и несколько других интерфейсов по мере необходимости в конструкторах контроллера. Он работает плавно, поэтому мне больше не приходилось делать с ним.
Всюду, что я читаю на WebAPI, мне сказали, что DI не будет работать так хорошо, используя Castle Windsor, говоря о проблемах с IDependencyResolver
и IDependencyScope
. Существует несколько обходных решений и способов решения этой проблемы, но мне непонятно, в чем проблема. Фрагменты кода включены, но предположение, что вы знаете, к какому классу они принадлежат, и как они вызывают, к сожалению, я этого не делаю. Кроме того, все примеры, которые я видел в Интернете, относятся к эксклюзивному проекту WebAPI, а не к проекту MVC4 с разумным вводом пары ApiController
. Я не знаю, как, или если это влияет на что-либо.
Почему я не работаю с моими стандартными контроллерами, не работая с контроллером API? Какую акробатику кода нужно делать, чтобы вызовы WebAPI и стандартные веб-вызовы работали в одном приложении?
Ответы
Ответ 1
Чтобы использовать Windsor с webapi, следуйте
http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor/
(BEH: фиксированная ссылка)
Читайте также
Замок Виндзор/ДелегированиеHandler/IPrincipal Injection (DI)/Инверсия управления (IoC) в веб-API ASP.NET
Вы можете использовать контроллеры webapi и MVC в одном приложении (я предпочитаю держать его отдельно), но маршрутизаторы и контроллеры factory отличаются друг от друга, и вам нужно настроить две разные конфигурации и перекрытия маршрутизации ручек...
Для MVC и Windsor вы можете найти отличный
Ответ 2
Конфигурация MVC существующего замка Windsor
Предполагая, что у вас установлены MVC и Castle Windsor аналогично учебному курсу Castle Windsor MVC, добавление IoC, чтобы заставить контроллеры Web API использовать инъекцию зависимостей очень просто с 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()
snip
IWindsorContainer container = new WindsorContainer()
.Install(
new LoggerInstaller()
//...,
, new ControllersInstaller()
);
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
return container;
Необходимые изменения
По сообщению Mark Seemann вам нужно войти в веб-API точку входа (состав) через 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 могут использовать ваши вложенные зависимости так же, как ваши контроллеры 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" };
}
}
Ответ 3
Следующий образец проекта дал мне ответ, который я искал. Он использует замок Виндзор для инъекций зависимости. Я смог использовать MVC-контроллеры вместе с контроллерами Web API в одном приложении.
mirajavora/WebAPISample
Здесь сообщение с подробным описанием:
Начало работы с веб-API ASP.NET