25

UserQuery、CustomerQueryのようなクラスがあり、それぞれIUserQuery、ICustomerQueryのようなインターフェイスを実装しています。バインディング構成では、すべてのインターフェイスをそれぞれのクエリでバインドする必要があります。

builder.RegisterType<UserQuery>().As<IUserQuery>().InstancePerRequest();
builder.RegisterType<CustomerQuery>().As<ICustomerQuery>().InstancePerRequest();

これはかなりうまく機能していますが、すべてのクラスXXX [Query]-> [I] XXX [Query]をバインドする代わりに、規則ベースのバインドを作成する方法があるかどうか疑問に思いました。

私はDIコンテナとしてAutoFacを使用しています。

4

3 に答える 3

36

私は AutoFac の経験豊富なユーザーではありません。ただし、いくつかの調査の後、以下のコードをテストして成功しました。

var assembly = Assembly.GetExecutingAssembly();

builder
    .RegisterAssemblyTypes(assembly)
    .AssignableTo<IQuery>()
    .AsImplementedInterfaces()
    .InstancePerRequest();

上記の IQuery インターフェイスは、使用しているすべてのクエリ インターフェイスから継承する必要がある単なるタグ インターフェイスです。あなたの例を使用して:

インターフェース

IUserQuery: IQuery
ICustomerQuery: IQuery

クラス

UserQuery: IUserQuery
CustomerQuery: CustomerQuery
于 2013-01-30T12:27:37.297 に答える
11

Autofacのアセンブリ スキャン機能を使用する必要があります。

インターフェイスまたは実装が基本クラス (例: QueryBase) または基本インターフェイス (例: IQuery) を共有している場合は、次のような登録用の説得メソッドを使用できます。gustavodidomenico の回答AssignableTo<>を参照してください。

ただし、共通の基本インターフェイス/クラスを使用できない場合があります。その場合、Whereどのクラスをどのように登録する必要があるかを検出するためのカスタム ロジックを使用できるメソッドを使用できます。

その場合、登録は大まかに次のようになります。

builder.RegisterAssemblyTypes(yourAssembly)
       .Where(t => t.IsClass && t.Name.EndsWith("Query"))
       .As(t => t.GetInterfaces().Single(i => i.Name.EndsWith(t.Name)));

名前が"Query"一致するインターフェイスで終わる特定のアセンブリのすべてのタイプを登録するためSomeNiceQuery、インターフェイスに登録しますISomeNiceQuery

于 2013-01-30T12:26:46.397 に答える
0

または、各タイプを最初に実装されたインターフェースまたはそれ自体として登録することもできます。

builder.RegisterAssemblyTypes(new[] { Assembly.GetAssembly(typeof(IUserQuery))})
        .Where(x=> x.IsClass && x.Name.EndsWith("Query"))
        .As(t => t.GetInterfaces().Any() ? t.GetInterfaces()[0] : t);
于 2016-11-22T10:06:16.367 に答える