模块已注册了如下所示的类型:
class MyType
{
public IEnumerable<IServer> Servers { get { ... } }
}
我想用容器注册每个服务器实例:
builder.Register(x => x.Resolve<MyType>().Servers).As<IEnumerable<IServer>>();
另外我想注册IServer的另一个实现
builder.RegisterType<AnotherServer>().As<IServer>().SingleInstance;
然后我想获得所有服务器 - union os Server属性和AnotherServer的实例:
public MyClass(IEnumerable<IServer> allServers)
{
}
但是,上述设置不起作用,因为注册IEnumerable的实际实例似乎会覆盖在请求IEnumerable时提供所有已注册实现的Autofac行为。
有什么方法可以达到我的目的吗?
答案 0 :(得分:0)
生成多个组件不可能有一个注册。
我可以看到两种解决问题的方法
IRegistrationSource
以解析IEnumerable<T>
。您可以查看CollectionRegistrationSource.cs了解如何操作IEnumerable
。 这样的事情:
public interface IContainer<T> {
IEnumerable<T> Values { get; }
}
public class MyType : IContainer<IServer>
{
public IEnumerable<IServer> Servers
{
get
{
yield return new Server1();
yield return new Server2();
}
}
IEnumerable<IServer> IContainer<IServer>.Values
{
get { return this.Servers; }
}
}
public class AggregatedEnumerableModule<T> : Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
if (registration.Activator.LimitType.IsArray)
{
Type elementType = registration.Activator.LimitType.GetElementType();
if (elementType == typeof(T))
{
registration.Activating += (sender, e) =>
{
IEnumerable<T> originalValues = (IEnumerable<T>)e.Instance;
IEnumerable<T> newValues = e.Context.Resolve<IContainer<T>>().Values;
IEnumerable<T> aggregatedValues = newValues.Concat(originalValues);
e.ReplaceInstance(aggregatedValues);
};
}
}
base.AttachToComponentRegistration(componentRegistry, registration);
}
}
然后
ContainerBuilder builder = new Autofac.ContainerBuilder();
builder.RegisterModule(new AggregatedEnumerableModule<IServer>());
builder.RegisterType<MyType>().As<IContainer<IServer>>();
builder.RegisterType<Server3>().As<IServer>();
IContainer container = builder.Build();
IEnumerable<IServer> pouets = container.Resolve<IEnumerable<IServer>>();