0

http://code.google.com/p/autofac/wiki/MultitenantIntegrationのドキュメントから

これは比較的複雑であるため、テナントがコントローラーをオーバーライドするのではなく、オーバーライド依存関係を提供できるように、ビジネス ロジックをコントローラーに渡される外部依存関係に分離することをお勧めします。

多くのアクションを持つデフォルトのコントローラーがあるとしましょう。Index アクションは、製品、在庫、店舗のデータの完全なリストを取得します。私の TenantB は、多くのアクションを持つ同じコントローラーを必要としていますが、Index アクションについては、売上のリストも取得したいと考えています。

このような小さな変更のためにコントローラー全体をオーバーライドする必要はないように思えます。これは、上記の引用文が言及していることですか?インデックスに挿入されるいくつかの外部メソッドを持つことができます。これは、デフォルトのテナントの場合、製品、在庫、および店舗を返すメソッドになりますが、TenantB は、売上も返すそのメソッドのオーバーライドを持ちますか?

私の仮定が正しければ、このタイプの実装を示すサンプルコードをどこかに知っている人はいますか?

4

1 に答える 1

1

その文の背後にある考え方は、インデックスアクション内のロジックを個別の依存関係に分離することです。

つまり、現在、おそらく次のようなコントローラーがあります。

public class MyController : Controller
{
  protected IDataService _dataService;
  public MyController(IDataService dataService)
  {
    this._dataService = dataService;
  }
  public virtual ActionResult Index()
  {
    var data = this._dataService.GetData();
    var model = new IndexModel()
    {
      Data = data
    };
    return this.View(model);
  }
  public virtual ActionResult OtherAction()
  {
    // other stuff...
  }
}

そのインデックスアクションでは、データを取得し、ビューに渡す前にデータに対してビジネスロジックを実行している可能性があります。

このような設計を使用すると、テナント固有の追加データを取得する必要があるため、コントローラーをオーバーライドする必要があります。これは実際にはそれほど難しいことではなく、追加のサービス依存関係に対してプロパティインジェクションを実行することにした場合は、機能するはずです。

public class TenantSpecificController : MyController
{
  // If you set up PropertiesAutowired on the tenant controller
  // registration, you'll get this property populated.
  public IOtherService OtherService { get; set; }
  public TenantSpecificController(IDataService dataService)
    : base(dataService)
  {
  }
  public override ActionResult Index()
  {
    var data = this._dataService.GetData();
    var otherData = this.OtherService.GetData();
    var model = new IndexModel()
    {
      Data = data
    };
    // You can't really change the model without changing the
    // view, so extended data goes in the ViewData or ViewBag
    this.ViewData["other"] = otherData;
    return this.View(model);
  }
}

しかし、ドキュメントのその文がほのめかしているのは、そのコントローラーにいくつかの派手なテナントオーバーライドロジックがあることがわかっている場合(コントローラーのオーバーライドは1回限りのシナリオでは簡単なので、1回限りではありません) )次に、次のように、ロジックをコントローラーから引き出します。

public class MyController : Controller
{
  protected IIndexModelGeneratorService _modelService;
  public MyController(IIndexModelGeneratorService modelService)
  {
    this._modelService = modelService;
  }
  public virtual ActionResult Index()
  {
    var model = this._modelService.BuildModel();
    return this.View(model);
  }
  public virtual ActionResult OtherAction()
  {
    // other stuff...
  }
}

次に、コントローラー/アクションレベルでテナントのオーバーライドを実行する代わりに、特定のサービスでテナントのオーバーライドを実行します。コントローラから他の依存関係にビジネスロジックを引き出しています。

明らかに、それはより拡張可能なデータを許可するためにモデルを変更することを意味するかもしれません...

public class IndexModel
{
  public DataObject Data { get; set; }
  public Dictionary<string, object> ExtendedData { get; set; }
}

...または、データサービスの実装で辞書を使用してデータを入力します。

public interface IIndexModelGenerator
{
  IndexModel BuildModel(ViewDataDictionary dict);
}

...したがって、呼び出すと、コントローラーはViewDataディクショナリを渡して、追加のデータをキャプチャします。

var model = this._modelService.BuildModel(this.ViewData);

アイデアは今でも当てはまります。これらがたくさんある場合は、テナントごとに異なるコントローラーを使用するよりも、ビジネスロジックをマルチテナントコンポーネントに分割する方が簡単な場合があります。

于 2012-12-06T16:30:50.830 に答える