替换Autofac中的注册

Vad*_*kan 6 autofac

我有一个进行数据处理的应用程序.有

class Pipeline {
  IEnumerable<IFilter> Filters {get; set;}
Run Code Online (Sandbox Code Playgroud)

我将过滤器实现注册为

builder.RegisterType<DiversityFilter>().As<IFilter>();
builder.RegisterType<OverflowFilter>().As<IFilter>();
...
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.现在,为了实验和微调,我希望能够使用程序(脚本)覆盖配置文件中的任何过滤器实现,该程序将从stdin读取数据,处理它并将数据发送到stdout.我已经实现了一个带有"fileName","args"和"RatherOf"自定义属性的模块,在xml中描述了模块并调用了它.

在模块中,我注册了我的"ExecutableFilter"但是如何让它"而不是"所需的服务?如果我尝试这样做:

builder.RegisterType<ExecutableFilter>().As<DiversityFilter>()
Run Code Online (Sandbox Code Playgroud)

然后我得到一个例外"类型'ExecutableFilter'不能分配给服务'DiversityFilter'." 好的,这是合乎逻辑的.但那么我有什么选择呢?

Nic*_*rdt 9

一旦您使用线控覆盖了IFilter"After"的注册,您将无法从容器中解析它,因为新注册将被激活,因此循环查找.

相反,创建并注册一个挂钩到过滤器创建的模块,并用'wire tapped'替换实例:

class WiretapModule : Module
{
  override void AttachToComponentRegistration(
           IComponentRegistration registration,
           IComponentRegistry registry)
  {
    if (registration.Services.OfType<KeyedService>().Any(
          s => s.ServiceKey == After && s.ServiceType == typeof(IFilter))) 
    {
      registration.Activating += (s, e) => {
        e.Instance = new WireTap((IFilter)e.Instance, new ExecuteProvider(fileName, args))
      };
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

(交叉发布到Autofac小组:https://groups.google.com/forum/#!topic /autofac/yLbTeuCObrU )