4


2

コンストラクターのパラメーター属性に基づいてautofacで依存関係を解決します

Autofacを使用しています。 コンストラクターパラメーターに適用する属性に基づいて、依存関係の異なる実装を挿入したい。 例えば:

class CustomerRepository
{
    public CustomerRepository([CustomerDB] IObjectContainer db) { ... }
}

class FooRepository
{
    public FooRepository([FooDB] IObjectContainer db) { ... }
}

builder.Register(c => /* return different instance based on attribute on the parameter */)
       .As();

属性は、正しいオブジェクトをインスタンス化するために使用できる接続文字列などのデータを提供します。

これどうやってするの?

2 Answer


9


「IObjectContainer」の異なる実装を「CustomerRepository」と「FooRepository」に提供したいようです。 その場合、属性はhttp://blogs.msdn.com/ericlippert/archive/2003/11/03/53333.aspx[thin metal ruler]になります。 代わりに、Autofacで複数の実装を実装する方法を紹介します。

( `.ContainerScoped()`などの呼び出しは簡潔にするために省略されています。)

まず、登録に名前を付けて、接続文字列ごとに「IObjectContainer」のバージョンを登録します。

builder
    .Register(c => new ObjectContainer(ConnectionStrings.CustomerDB))
    .As()
    .Named("CustomerObjectContainer");

builder
    .Register(c => new ObjectContainer(ConnectionStrings.FooDB))
    .As()
    .Named("FooObjectContainer");

次に、リポジトリ登録の特定のインスタンスを解決します。

builder.Register(c => new CustomerRepository(
    c.Resolve("CustomerObjectContainer"));

builder.Register(c => new FooRepository(
    c.Resolve("FooObjectContainer"));

これにより、リポジトリに構成情報がなくなります。

class CustomerRepository
{
    public CustomerRepository(IObjectContainer db) { ... }
}

class FooRepository
{
    public FooRepository(IObjectContainer db) { ... }
}


0


Bryanの答えは、複数のリポジトリがあり、コンストラクタパラメータがほとんどない間に十分です。 しかし、多くのルートがある場合、ルートを設定することは困難です。 これを実現するには、インターフェイスの解決時にクラスのメタデータをスキャンします。 パラメータに関する情報を取得すると、実際の実装を解決できます。 私の答えhttps://stackoverflow.com/a/19056430/974487 [こちら]をご覧ください。