2017-08-18 9 views
2

I持ってC#Unityは、N個のインスタンスを追加することにより、登録したタイプのリストを登録し、解決

public ServiceManagement(List<IWorker> workers) 

を受け取り、私は労働者が登録されていたサービス:

this.Container.RegisterType<IWorker, Worker> 

は、私がお伝えしたいと思いますそのリストを解決してWorkerのN個のインスタンスを正確に作成するときは、

誰でも手助けできますか?

私は次のことを試してみました:

ではなく、リストの配列を受信し、そのように登録:

for (int i = 0; i < N; i++) 
{ 
    this.Container.RegisterType<IWorker, Worker>(i.ToString()); 
} 

しかし、異なるIWorkerの実装ではないと同じのため、この唯一の作品。

ありがとうございます!

答えて

1

ファクトリを作成しても、ファクトリ自体に渡さない限り、ワーカークラスの依存関係は解決されません。これは、過剰なオーバーヘッドを追加するワーカーの種類ごとにファクトリがあることを意味します。

タイプを登録するときにワーカーをN回解決して、それらのインスタンスにリストを登録することで行うことができますが、これは解決方法がRegisterTypeの順序に依存することになります。実際に必要となる前にインスタンスを解決することもあります。

結局私はInjectionFactoryをした:

this.Container.RegisterType<List<IWorker>>(new InjectionFactory(c => 
     { 
      var workers = new List<IWorker>(); 

      for (int i = 0; i < N; i++) 
      { 
       workers.Add(c.Resolve<IWorker>()); 
      } 

      return workers; 
     })); 

必要なときにのみインスタンスを解決し、Unityが独自にIWorkerの依存関係を解決してくれますこの方法です。

+1

私はそれが最善のアプローチだと思います。私の答えを見てください。 :) –

1

同じことを複数回登録しないでください。 あなたがするべきことは、あなたの労働者の工場を作ることです。インスタンスの数を工場に渡します。次に、サービスコンストラクタで、リスト自体を作成するのではなく、リストを作成するファクトリを渡します。

コンテナでは、ファクトリを登録します。異なるオブジェクト型をサービスに渡す場合は、ファクトリを交換するだけです。

いくつかのサンプルコード:

public class WorkerFactory :IFactory<IWorker> 
{ 
public IEnumerable<IWorker> Create(int n) 
{ 
var workers = new List<IWorker>(); 
for(int i = 0; i<n;i++) 
workers.Add(new Worker()); 
return workers; 
} 
} 

public ServiceManagement(IFactory<IWorker> workersFactory) 
{ 
Workers = workersFactory.Create(5); 
} 
+0

ありがとう、ありがとう –

+0

作業員が依存性を持っているので、私がUnityによって解決されたかったので、 "new Worker()"を避けようとして以来、まだまだ辛いです。 –

0

私はCrekate答えを好むが、あなたはまだ些細な道を行くしたい場合、これは動作するはずです:

 const int N = 5; 
     UnityContainer container = new UnityContainer(); 

     container.RegisterType<IService, ServiceManagement>(); 
     for (int i = 0; i < N; i++) 
     { 
      container.RegisterType<IWorker, Worker>(i.ToString()); 
     } 

     container.RegisterType<IList<IWorker>, IWorker[]>(); 

     var service = container.Resolve<IService>(); 
     Console.WriteLine("count:"+service.RefCount()); 

とするためのいくつかのより多くのコードそれほど重要ではありません答:私はこの方法をやってしまった

public interface IService 
    { 
     int RefCount(); 
    } 
    public interface IWorker 
    { 
    } 

    public class ServiceManagement:IService 
    { 
     IList<IWorker> _workers; 
     public ServiceManagement(IList<IWorker> workers) 
     { 
      _workers = workers ?? new List<IWorker>(0); 
     } 
     public int RefCount() 
     { 
      return _workers.Count; 
     } 
    } 

    public class Worker : IWorker 
    { 
    } 
+0

これは実際に私が目的としていたものでした。あなたが別の実装を指定しない限り、質問には機能しません –

0

複数の名前付き登録を作成する必要はありません。名前付き登録は、通常、名前付き登録が異なる場合に使用されます。例えば異なる実装タイプ、または異なる依存関係など

工場での実装は機能しますが、別のファクトリクラスを作成するのではなく、UnityのInjectionFactoryを使用してください。これにより、別個のファクトリクラスの作成が節約され、サービスパラメータは、依存関係を提供できるオブジェクトではなく、実際の依存関係になります。別の利点は、ファクトリクラスがUnityに依存しないことです(ファクトリクラスでResolve()を使用して、ファクトリが返すオブジェクトのオブジェクトグラフを構築することを前提とします)。た。servicemanagementとのため

var container = new UnityContainer(); 

container.RegisterType<IWorker, Worker>(); 
container.RegisterType<List<IWorker>>(new InjectionFactory(c => 
{ 
    var workers = new List<IWorker>(); 
    for (var i = 0; i < 5; i++) 
    { 
     workers.Add(c.Resolve<IWorker>()); 
    } 

    return workers; 
})); 

var service = container.Resolve<ServiceManagement>(); 

List<IWorker>異なるが必要な場合(例えば、1つのリスト:以下の例では

はその後、我々は適切にファクトリクラスを作成したり、カスタム工場に IUnityContainerインスタンスを渡さず IWorkerを解決することができますOrderManagementの異なるリスト)、それぞれの実装を登録してから、適切なサービスに名前を付けることができます。

var container = new UnityContainer(); 

container.RegisterType<IWorker, Worker>(); 

container.RegisterType<List<IWorker>>(typeof(ServiceManagement).Name, 
    new InjectionFactory(c => 
    { 
     var workers = new List<IWorker>(); 
     for (var i = 0; i < 5; i++) 
     { 
      workers.Add(c.Resolve<IWorker>()); 
     } 

     return workers; 
    })); 

container.RegisterType<List<IWorker>>(typeof(OrderManagement).Name, 
    new InjectionFactory(c => 
    { 
     var workers = new List<IWorker>(); 
     for (var i = 0; i < 20; i++) 
     { 
      workers.Add(c.Resolve<IWorker>()); 
     } 

     return workers; 
    })); 

container.RegisterType<ServiceManagement>(
    new InjectionFactory(c => new ServiceManagement(c.Resolve<List<IWorker>>(typeof(ServiceManagement).Name)))); 
container.RegisterType<OrderManagement>(
    new InjectionFactory(c => new OrderManagement(c.Resolve<List<IWorker>>(typeof(OrderManagement).Name)))); 

var service = container.Resolve<ServiceManagement>(); 
var order = container.Resolve<OrderManagement>(); 
+0

まあまあ、私がやったことは、あなたが早く答えてくれたと思う、私は時間の束を保存しました:) –

関連する問題