2014-03-28 69 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