Подтвердить что ты не робот

IoC: Замок Виндзор и WebAPI

У меня есть сайт MVC4 с использованием Castle Windsor, к которому я хочу добавить некоторые вызовы WebAPI, поэтому я начинаю немного копаться в интерфейсах.

Теперь я не знаю входы и выходы IoC; Я последовал за учебником о том, как настроить Castle Windsor в моем проекте, введя IUnitOfWorkFactory и IApplicationService в качестве общедоступных свойств в базовом контроллере и несколько других интерфейсов по мере необходимости в конструкторах контроллера. Он работает плавно, поэтому мне больше не приходилось делать с ним.

Всюду, что я читаю на WebAPI, мне сказали, что DI не будет работать так хорошо, используя Castle Windsor, говоря о проблемах с IDependencyResolver и IDependencyScope. Существует несколько обходных решений и способов решения этой проблемы, но мне непонятно, в чем проблема. Фрагменты кода включены, но предположение, что вы знаете, к какому классу они принадлежат, и как они вызывают, к сожалению, я этого не делаю. Кроме того, все примеры, которые я видел в Интернете, относятся к эксклюзивному проекту WebAPI, а не к проекту MVC4 с разумным вводом пары ApiController. Я не знаю, как, или если это влияет на что-либо.

Почему я не работаю с моими стандартными контроллерами, не работая с контроллером API? Какую акробатику кода нужно делать, чтобы вызовы WebAPI и стандартные веб-вызовы работали в одном приложении?

4b9b3361

Ответ 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