同じインターフェースの複数の実装を持つ Autofac

探している他の人のために、私はこれに出くわしました. IEnumerable の暗黙的なサポートを使用できます。将来の使用のために書き留めました。

基本的に、後で使用できる IEnumerable として名前 (またはその他の条件) でアセンブリ型を登録できます。このアプローチの私のお気に入りの部分は、メッセージ ハンドラーを追加し続けることができ、同じ基準に固執する限り、後で基準に触れる必要がないことです。

Autofac 登録:

builder.RegisterAssemblyTypes(typeof (LoggingMessageHandler).Assembly)
  .Where(x => x.Name.EndsWith("MessageHandler"))
  .AsImplementedInterfaces();

消費クラス:

public class Foo
{
  private readonly IEnumerable<IMessageHandler> _messageHandlers

  public Foo(IEnumerable<IMessageHandler> messageHandlers)
  {
    _messageHandlers = messageHandlers;
  }

  public void Bar(message)
  {
    foreach(var handler in _messageHandlers)
    {
      handler.Handle(message)
    }
  }
}

Autofac は Decorators をサポートしています。


ここに 4 つのオプションがあります:https://autofaccn.readthedocs.io/en/latest/faq/select-by-context.html

オプション 1:インターフェイスを再設計する

ILoggingMessageHandler , IDoSomethingMessageHandler 

オプション 2:登録を変更する

builder.Register(ctx => new FinalHandler(ctx.Resolve<LoggingMessageHandler >()));
or
builder.Register(ctx => new FinalHandler(ctx.Resolve<IDoSomethingMessageHandler >()));

オプション 3:キー付きサービスを使用する

builder.RegisterType<FinalHandler>()
           .WithParameter(
             new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(IMessageHandler),
               (pi, ctx) => ctx.ResolveKeyed<ISender>("something")));

オプション 4:メタデータを使用する

public class FinalHandler
{
  public FinalHandler([WithMetadata("sendBy", "something")] IMessageHandler messageHandler) { ... }
}