2014-03-28 70 views
1

我找不到解决将集合解析为基类的问题。我有一个使用AutoFac解决处理以下伪测试类:使用AutoFac解析泛型集合

namespace Test { 

    interface IEventEmitter {} 

    interface IEventHandler {} 

    interface IEventHandler<in T> : IEventHandler where T: IEventEmitter {} 

    interface ISomeClass : IEventEmitter {} 

    class SomeClass : ISomeClass 
    { 
     // 2 handlers should be resolved here, not one! 
     public SomeClass(IEnumerable<IEventHandler> handlers) {} 
    } 

    class GenericEventHandler : IEventHandler {} 

    class DedicatedEventHandler : IEventHandler<ISomeClass> {} 

    [TestClass] 
    class TestClass 
    { 
     [TestMethod] 
     private void TestHandlers() 
     { 
      var builder = new ContainerBuilder(); 

      // registered in order to resolve handlers 
      builder.RegisterType<SomeClass>().As<ISomeClass>(); 

      builder.RegisterType<GenericEventHandler>().As<IEventHandler>(); 

      builder.RegisterType<DedicatedEventHandler>().As<IEventHandler<ISomeClass>>(); 

      var container = builder.Build(); 

      using (var scope = container.BeginLifetimeScope()) 
      { 
       var instanceWithHandlers = scope.Resolve<ISomeClass>(); 
      } 
     } 
    } 
} 

请注意,我注册一个专门的处理程序ISomeClass接口,以及一个通用 一个任何类型的活动发射器。我的期望是SomeClass构造函数将被注入2个处理程序 - 通用的和专用的。

不幸的是,事实并非如此。我在这里做错了什么?

谢谢。

回答

2

当您注册与As接口Autofac不会自动注册其基本接口。

所以,你需要手动告诉Autofac您DedicatedEventHandler也是IEventHandler有:

builder.RegisterType<DedicatedEventHandler>() 
     .As<IEventHandler<ISomeClass>>() 
     .As<IEventHandler>(); 

如果你想与所有的接口注册类型,你可以使用AsImplementedInterfaces方法。

所以上面登记的等值如下:

builder.RegisterType<DedicatedEventHandler>() 
     .AsImplementedInterfaces(); 
+0

哦btw-由于我们这里登记了两个接口,专用的出现在任何IEventHandler集合中,是否正确?有没有一种方法可以执行完整的匹配,以便将解析仅限于SomeClass? – ichen

+0

是的,只要你请求'IEnumerable ',就会包含'Dedicated'',所以你不能仅仅为SomeClass限制这个。 Autofac不是最好的上下文绑定,但您可以查看命名注册功能或https://github.com/autofac/Autofac/wiki/Typed-Named-And-Keyed-Services或元数据支持:https ://github.com/autofac/Autofac/wiki/Metadata – nemesv

+0

是的,我认为命名/键控服务会更好,尽管我能找到一个相当难看的方法来解决它。 builder.Register(c => new SomeClass(c.Resolve >() .Concat(c.Resolve >()。Cast ())))。As (); – ichen