8
      var servers = new List<IChecker> {
      //Server1
      new DatabaseSystem { ServerName = "ANTIVIRUS" },
      new DatabaseSizes  { ServerName = "ANTIVIRUS"},
      new DiskBackup { ServerName = "ANTIVIRUS"},
      new SqlServerEventLog { ServerName="ANTIVIRUS"},
      new DiskSystem { ServerName="ANTIVIRUS"}, 
      //Server1
      new DatabaseSystem { ServerName="SEJKG-S-DB01" },
      new DatabaseSizes  { ServerName = "SEJKG-S-DB01"},
      new DiskBackup { ServerName = "SEJKG-S-DB01"},
      new SqlServerEventLog { ServerName="SEJKG-S-DB01"},
      new DiskSystem { ServerName="SEJKG-S-DB01"},
  };

  var builder = new ContainerBuilder();            
  builder.RegisterInstance(notifiers).As<IList<INotifier>>();     
  builder.RegisterInstance(servers).As<IList<IChecker>>();
  builder.Register(c => new ServerChecker(c.Resolve<IList<IChecker>>(),  c.Resolve<IList<INotifier>>()));
  return builder.Build();

「where server = new List {..}」を Container Builder に登録する方法に問題があります。iChecker のリストがパラメーターとして ServerChecker に渡されました。多くのことを解決できましたが、サーバーの通常のリストははるかに大きくなります。

4

1 に答える 1

16

Autofac には、複数の個別のアイテムを登録できる暗黙的なコレクション サポートがあり、これらのアイテムの IEnumerable を解決すると、すべての登録が取得されます。

var builder = new ContainerBuilder();
builder.RegisterType<FirstType>().As<IDependency>();
builder.RegisterType<SecondType>().As<IDependency>();
builder.RegisterType<ThirdType>().As<IDependency>();
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
  var allDependencies = scope.Resolve<IEnumerable<IDependency>>();
  // allDependencies will contain all three of the registered types.
}

これにより、事前にリストを実際に作成する必要がないため、登録を大幅に簡素化できます。「IChecker」または「INotifier」インスタンスをそれぞれ直接登録し、それらの IEnumerable を解決できます。

「ServerChecker」コンストラクターを変更して、IList ではなく IEnumerable を使用できる場合は、これで完了です。c.Resolve() を実行する必要はもうありません。とにかく、IList はコレクションを後で変更できることを意味するため、おそらくより良い設計です。これはおそらくあなたが望むものではありません。(ServerChecker が IEnumerable の内容を独自のリストにコピーするため、ローカル コピーを変更できる可能性がありますが、中央の依存関係の内容をそのように変更できる、または変更する必要があると人々に考えてほしくないでしょう。)

IList でなければならない場合は、その場でリストを作成する別の登録を追加できます。

builder
  .Register(c => new List<IDependency>(c.Resolve<IEnumerable<IDependency>>()))
  .As<IList<IDependency>>();

そうすれば、「ServerChecker」の解決で c.Resolve<...>() 呼び出しを行うことを回避できます。Autofac は、特定のタイプのリストを作成する方法を突然認識します。

本当に使いたい場合は、誰かが IList を解決しようとすると Autofac が自動的に IEnumerable の解決を行い、リストを作成するように、カスタム Autofac RegistrationSource を追加できます...しかし、それはおそらく必要以上のものです.

于 2012-04-24T15:41:11.573 に答える