8

Autofac 3.0はMultitenantIntegrationをサポートし、そのプレビューリリースは現在リリースされています。試してみるために、次の構成でASP.NETWebAPIアプリケーションを作成しました。

public class Global : System.Web.HttpApplication {

    protected void Application_Start(object sender, EventArgs e) {

        var config = GlobalConfiguration.Configuration;
        config.Routes.MapHttpRoute("Default", "api/{controller}");
        RegisterDependencies(config);
    }

    public void RegisterDependencies(HttpConfiguration config) {

        var builder = new ContainerBuilder();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // creates a logger instance per tenant
        builder.RegisterType<LoggerService>().As<ILoggerService>().InstancePerTenant();

        var mtc = new MultitenantContainer(
            new RequestParameterTenantIdentificationStrategy("tenant"),
            builder.Build());

        config.DependencyResolver = new AutofacWebApiDependencyResolver(mtc);
    }
}

それは仕事を成し遂げ、テナントごとにLoggerServiceインスタンスを作成します。ILoggerServiceこの段階では、解決できなかった2つの問題があります。

  1. RequestParameterTenantIdentificationStrategyこのデモアプリケーション専用のTenantIdentificationStrategyとして、ここで提供されている箱から出して使用しました。インターフェイスを実装することで、カスタムTenantIdentificationStrategyを作成できITenantIdentificationStrategyます。ただし、のTryIdentifyTenant方法では、APIをホスティングに依存しないようにするため、ASP.NET Web API環境では望ましくないITenantIdentificationStrategy静的インスタンスに依存するようになります(この作業をに委任できることはわかっています)HttpContext.Currentホスティングレイヤーですが、私はむしろしたくないです)。静的インスタンスに依存しない方法でこれを実現する別の方法はありますか?
  2. また、以下のようにテナント固有のインスタンスを登録する機会があります。

    mtc.ConfigureTenant("tenant1", cb => cb.RegisterType<Foo>()
                                        .As<IFoo>().InstancePerApiRequest());
    

    ただし、私の状況の1つでは、コンストラクターパラメーターを介してテナント名を渡す必要があり、次のようなものが必要です。

    mtc.ConfigureTenant((cb, tenantName) => cb.RegisterType<Foo>()
                                        .As<IFoo>()
                                        .WithParameter("tenantName", tenantName)
                                        .InstancePerApiRequest());
    

    現在、そのようなAPIはありません。これを達成する別の方法はありますか、またはこの種の要件は意味がありませんか?

4

1 に答える 1

5

マルチテナント サポートは長い間利用可能でしたが、NuGet パッケージを用意したのは 3.0 が初めてです。:)

文書化されているように、これはテナントを識別するための 1 つの可能な (推奨さRequestParameterTenantIdentificationStrategyれない) 方法を示す非常に単純な例です。運用コンテキストに基づいてテナントを識別する方法を自分で選択する必要があります。値、環境変数、または現在の環境のその他のものからのものである可能性があります。を使用したくない場合は、使用しないでください。その情報をどこから入手するかは、あなた次第です。web.configHttpContext.Current

( RPTIStrategy- 推奨されない部分は、テナント ID メカニズムとしてクエリ文字列または要求パラメーターを使用することです。私HttpContextは実稼働アプリで使用しており、正常に動作します。実際に必要になる前に抽象化できるものは非常に限られています。地金に触れてください。)

主に、テナントが解決プロセスを通過しないため、要求しているラムダ登録構文をすぐに提供する方法はありません。解決プロセスは次のとおりです。

  1. 戦略でテナントを特定します。
  2. テナントの構成された有効期間スコープを見つけます。
  3. 標準の Autofac Resolve スタイルの構文を使用します。

これは意図的に単純化され、既存の操作に類似しています。解決時に、テナントに属するサブライフタイム スコープはテナント ID でタグ付けされますが、解決操作ではテナント ID が認識されないため、ラムダは機能しません (おそらく機能しません)。 Autofac が機能する方法の基本的な内部構造が変更されるため、近いうちに変更されます)。

探しているものを達成するために、InstancePerTenant登録時に拡張機能の組み合わせを使用できます...

var builder = new ContainerBuilder();
builder.RegisterType<Foo>().As<IFoo>().InstancePerTenant();

...そしてITenantIdentificationStrategy、コンテナに依存関係として登録します。

builder.Register(myIdStrategy).As<ITenantIdentificationStrategy>();

ITenantIdentificationStrategy次に、テナント ID を直接ではなく、クラスに取得させます。代わりに、戦略を使用してテナント ID を取得してください。

本当に凝りたい場合は、ID 戦略を解決するキー付きラムダを登録してから、テナント ID を取得できます。次に、キー付きサービスを使用して、オブジェクトにパラメーター登録を追加できます。(今から記憶で行くので、ここで構文を再確認する必要がありますが、次のようになります...)

builder.Register(c => 
       {  var s = c.Resolve<ITenantIdentificationStrategy>();
          object id;
          s.TryIdentifyTenant(out id);
          return id;
       }).Keyed<object>("tenantId");

builder.RegisterType<Foo>()
       .As<IFoo>()
       .WithParameter(
         (pi, c) => pi.Name == "tenantId",
         (pi, c) => c.ResolveKeyed<object>("tenantId"))
       .InstancePerApiRequest();

繰り返しますが、あなたはそれについて私に再確認したいと思うでしょうが、あなたが望むものを得るためにそれ(またはマイナーなバリエーション)がうまくいくはずです.

于 2012-12-24T04:57:02.170 に答える