web-dev-qa-db-ja.com

IoC:Castle WindsorとWebAPI

Castle Windsorを使用しているMVC4サイトにWebAPI呼び出しを追加したいので、インターウェブについて少し調べてみます。

今、私はIoCの内外を知りません。プロジェクトにCastle Windsorをセットアップする方法のチュートリアルに従い、IUnitOfWorkFactoryIApplicationServiceをベースコントローラーのパブリックプロパティとして注入し、コントローラーコンストラクターで必要に応じて他のいくつかのインターフェイスを注入しました。 。それは水泳で機能するので、私はそれでこれ以上何もする必要がありませんでした。

WebAPIで読んでいるところはどこでも、Castle Windsorを使用するとDIがうまく機能しないと言われ、IDependencyResolverIDependencyScopeの問題について話します。この問題を回避する方法にはいくつかの回避策と実装がありますが、私には明確ではないのは問題が何であるかです。コードスニペットは含まれていますが、想定されているのは、それらがどのクラスに属していて、どのように呼び出されているかを知っているということです。さらに、私がオンラインで見たすべての例は、独占的なWebAPIプロジェクトを参照しており、いくつかのApiControllersが賢明に投げ込まれたMVC4プロジェクトを参照していません。

標準コントローラーで使用しているものがAPIコントローラーで使用できないのはなぜですか? WebAPI呼び出しと標準のWeb呼び出しを同じアプリケーションで機能させるには、どのような種類のコードアクロバットが必要ですか?

20
Jeremy Holovacs

Windapiをwebapiで使用するには、次のようにしてください http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor/ (BEH:fixed link)

また読む Castle Windsor/DelegatingHandler/IPrincipal Dependency Injection(DI)/ Inversion of Control(IoC)in ASP.NET Web API

同じアプリでwebapiとMVCコントローラーを使用できますが(別々にしておくことをお勧めします)、ルーティングとコントローラーファクトリは異なり、2つの異なる構成をセットアップしてルーティングの重複を処理する必要があります... MVCとウィンザーの場合は、すごい

12
Crixo

既存のCastle Windsor MVC構成

Castle Windsor MVCチュートリアル と同様にMVCとCastle Windsorをセットアップしていると仮定すると、IoCを追加して、依存関係注入を利用するWeb APIコントローラーを取得するのは Mark Seemannの投稿(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の投稿から、IHttpControllerActivatorを通じてWeb APIの entry point(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" };
    }
}
_
11
lko

次のサンプルプロジェクトは、私が探していた答えをくれました。依存関係の注入にCastle Windsorを使用します。同じアプリケーションでWeb APIコントローラーと一緒にMVCコントローラーを使用できました。

mirajavora/WebAPISample


詳細は次のとおりです。

ASP.NET Web APIの概要

6

最初にIkoが述べたように、IHttpControllerActivatorを実装するクラスを作成する必要があります。

次に、ContainerBootstrapperBootstrap()に以下を追加します。デフォルトを実装されたものに置き換えます。

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

最後に、ここでは触れていませんが、それがなければ私は機能しませんでした。IWindsorInstallerサービスをinstall()内に実装して、次のコードを追加する必要があります。

_container.Register(
    Classes.FromThisAssembly()
    .BasedOn<ApiController>()
    .LifestyleTransient()    
);
_
1
Ali Ezzat Odeh