2

たとえば、インターフェイスがありますISomeServiceISomeService共通のサービスを提供しますが、実装は異なる場合があります。そのため、それらには異なる依存関係があります。

検討:

interface ISomeService
{
     void DoSomething();
}

class SomeServiceA : ISomeService
{
     public SomeServiceA(DependencyOne one, DependencyTwo two)
     {
     }


     public void DoSomething()
     {
     }
}

class SomeServiceB : ISomeService
{
     public SomeServiceB(DependencyThree three)
     {
     }

     public void DoSomething()
     {
     }
}

さて、現実には、 ISomeService への依存関係をコントローラーに追加するだけでは完了できません。ユーザーからの指示に基づいて IService の実装を選択する必要があり、ユーザーが選択したサービスの複数のコピーを作成する必要がある場合があります。

おそらく、必要な ISomeService のインスタンスをタイプ別に解決できるクラスがあると思います。

class SomeServiceProvider
{
    public T Get<T>()
        where T : ISomeService
    {
          // uh oh, this is starting to have a bad smell... do I call the container? that's no good
    }

}

だから私はできた

class SomeController
{
     SomeServiceProvider ServiceProvider { get; set; }

     public SomeController(ServiceProvider provider)
     { ServiceProvider = provider; }

     public void SomeAction(string serviceName)
     {
          ISomeService someService;
          if (serviceName.Equals('SomeServiceA')) someService = ServiceProvider.Get<SomeServiceA>();
          else someService = ServiceProvider.Get<SomeServiceB>();
          someService.DoSomething();
     }

}

Autofac のデリゲート ファクトリはここでは適切ではないようです。それ以外の場合はどうすればよいかわかりません (サービス ロケータを使用する場合を除く)。推奨事項はありますか?

4

1 に答える 1

2

これはあなたが必要とするものですか? サービスの種類、名前、およびキー

サービスは、サービス名を使用してさらに識別できます。この手法を使用すると、Named() 登録メソッドが As() に置き換わります。

builder.Register<OnlineState>().Named<IDeviceState>("online");

名前付きサービスを取得するには、ResolveNamed() メソッドを使用します。

var r = container.ResolveNamed<IDeviceState>("online");
于 2010-09-22T00:11:53.067 に答える