事件总线的代理 - 如何在OnActivating事件</t>期间解析IEnumerable <t>

时间:2015-04-07 08:54:19

标签: c# autofac

考虑我有一些接口,如:IFirstEvent等等。现在,我可以有多个IFirstEvent接口的实现。我想在ContainerBuilder中注册所有实现,以便在实现(和其他Autofac功能)中使用依赖注入。接下来,我想将IFirstEvent替换为将调用其他实现的代理类(在解析时)(我想注入单个IFirstEvent而不是IEnumerable<IFirstEvent>以便使用它)。 我写了以下片段:

var localEventType = typeof(IFirstEvent);
builder.RegisterAssemblyTypes(this.assemblies)
       .AssignableTo(localEventType)
       .As(localEventType)
       .InstancePerRequest()
       .OnActivating(ctx =>
                     {
                         var allImplementations =
                                  (IEnumerable)
                                  ctx.Context
                                     .Resolve(typeof(IEnumerable<>)
                                       .MakeGenericType(localEventType));

                         var proxy = MultiInterfaceProxy.For(
                                          localEventType, 
                                          allImplementations);
                         ctx.ReplaceInstance(proxy);
                     });

不幸的是,注册抛出了关于循环依赖的错误(很明显 - 在解析IFirstEvent的集合时,每个项都将被代理类替换)。

那么,我如何用代理替换实例,并且能够找到并解决接口的所有具体实现? 我不想手动搜索程序集的具体实现,因为我需要手动创建实例(我想避免它,以便让autofac管理lifetimescopes)。也许别无他法?

1 个答案:

答案 0 :(得分:0)

避免循环依赖的一种可能方法是使用密钥服务注册您的实现,然后将代理注册为您的服务:

var localEventType = typeof(IFirstEvent);
builder.RegisterAssemblyTypes(this.assemblies)
      .AssignableTo(localEventType)
      .Keyed(ProxyBuilder.ProxyKey, localEventType)
      .InstancePerRequest(); 

builder.Register(c =>
{
   Type enumerableEventType = typeof(IEnumerable<>).MakeGenericType(localEventType);
   IEnumerable implementations = (IEnumerable)c.ResolveKeyed(ProxyBuilder.ProxyKey, 
                                                             enumerableEventType);

   var proxy = MultiInterfaceProxy.For(localEventType, 
                                       implementations);

});

ProxyBuilder.ProxyKey是常数。即:

public static class ProxyBuilder
{
    public static readonly Object ProxyKey = new Object();
}