0

コントローラ

public class LocationsController : ApiController
{
    private readonly IMediator _mediator;

    public LocationsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    public IEnumerable<Place> Get()
    {
        return _mediator.Send(new GetLatestMapData<Place>());
    }
}

Get() アクションの最初の要求で、Handler は SimpleInjector によってインスタンス化され、正しく実行されます。

2 番目のリクエスト (ブラウザで F5 キーなど) では、次のエラーで失敗します。

タイプ .... のリクエストのハンドラーが見つかりませんでした。

コンテナーまたはサービス ロケーターが正しく構成されていないか、コンテナーにハンドラーが登録されていません。

および内部例外:

破棄されたオブジェクトにアクセスできません。

オブジェクト名: 「ThreadLocal オブジェクトは破棄されました。」

OWIN スタートアップ

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // SimpleInjector
        var container = CompositionRoot.CreateContainer();

        var config = GlobalConfiguration.Configuration;

        config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

        // Routing
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}",
            new { id = RouteParameter.Optional });

        config.EnsureInitialized();

        app.UseWebApi(config);
    }
}

WebAPI プロジェクトの SimpleInjector IPackage

public class Installer : IPackage
{
    public void RegisterServices(Container c)
    {
        c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

        c.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    }
}

ハンドラーが正しく作成され、最初のリクエストの後に破棄されていると思います。理由はわかりませんが、後続のリクエストで Handler が再作成されません。WebApiRequestLifestyle を「スコープの終了時に破棄しない」に変更すると、すべてのリクエストで機能するため、これを知っています。

c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(false
/*disposeInstanceWhenScopeEnds*/);

質問

  1. disposeInstanceWhenScopeEndsパラメータを false に設定しておく必要がありますか?
  2. そうでない場合、正しい解決策は何ですか?
  3. これはLifetimeScopeDecorator を作成することで以前に解決されているようですが、この機能は SimpleInjector WebApi 統合ライブラリによって既に提供されているのでしょうか? 私は何が欠けていますか?

(そして読んでくれてありがとう)

4

2 に答える 2

0

このリンクは、依存関係の解決と IDependencyResolver / IDependencyScope インターフェイスの使用に関する適切なガイダンスを提供します。

すぐに、少しトリッキーになりがちな寿命に触れていることがわかります。

このセクションは特に興味深いものです。

依存範囲とコントローラーの有効期間

コントローラはリクエストごとに作成されます。オブジェクトの有効期間を管理するために、IDependencyResolver はスコープの概念を使用します。

HttpConfiguration オブジェクトにアタッチされた依存関係リゾルバーには、グローバル スコープがあります。Web API は、コントローラーを作成するときに、BeginScope を呼び出します。このメソッドは、子スコープを表す IDependencyScope を返します。

次に、Web API は子スコープで GetService を呼び出してコントローラーを作成します。要求が完了すると、Web API は子スコープで Dispose を呼び出します。Dispose メソッドを使用して、コントローラーの依存関係を破棄します。

従来、サービスのブートストラップはアプリの起動時に 1 回行われ、ご存知のようにその時点で依存関係が解決されていました。ワーカー プロセスがシャットダウンしている場合 (アクティビティがない場合など) にのみ、dispose が呼び出されます。

通常、使用後に破棄することが不可欠でない限り、解決されたインスタンスがライフサイクルの間残るのはごく普通のことだと思います。ただし、指定された例では、リクエストが完了したら正しく破棄する必要があることを説明しています。そのため、ガイダンスとして提供されている例を使用して、インスタンスを正しく破棄することをお勧めします。

これは、IoC と WebApi を使用するときに役立ちました。これが役立つことを願っています!

于 2016-09-22T15:08:03.017 に答える