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”构造函数更改为采用 IEnumerable 而不是 IList,那么您就完成了- 您不再需要执行 c.Resolve() 操作。无论如何,这可能是一个更好的设计,因为 IList 意味着可以稍后修改集合,这可能不是您想要的。(可能是 ServerChecker 将 IEnumerable 的内容复制到它自己的列表中,以便您可以修改本地副本,但您不希望人们认为他们可以或应该像这样修改中央依赖项的内容。)

如果它必须是 IList,您可以添加另一个动态创建列表的注册:

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

这样,您仍然可以避免在“ServerChecker”的分辨率中调用 c.Resolve<...>() - Autofac 会突然知道如何创建特定类型的列表。

如果你真的想看中它,你可以添加一个自定义 Autofac RegistrationSource这样如果有人试图解析 IList Autofac 会自动解析 IEnumerable 并创建一个列表......但这比你可能需要的多一点.

于 2012-04-24T15:41:11.573 回答