Autofac:注册多个

时间:2015-02-19 14:18:51

标签: c# autofac

模块已注册了如下所示的类型:

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行为。

有什么方法可以达到我的目的吗?

1 个答案:

答案 0 :(得分:0)

生成多个组件不可能有一个注册。

我可以看到两种解决问题的方法

  1. 创建新的IRegistrationSource以解析IEnumerable<T>。您可以查看CollectionRegistrationSource.cs了解如何操作
  2. 在激活期间使用模块替换IEnumerable
  3. 这样的事情:

    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>>();