2012-08-08 79 views
8

,我發現了以下錯誤:Ninject ActivationException:錯誤激活IAlertManagement

Test method: BootStrapperTest.Can_Create_Alert_Management_Object threw exception: Ninject.ActivationException: 
Error activating IAlertManagement No matching bindings are available, and the type is not self-bindable. 

Activation path: 
1) Request for IAlertManagement 

Suggestions:  
1) Ensure that you have defined a binding for IAlertManagement.  
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.  
3) Ensure you have not accidentally created more than one kernel.  
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.  
5) If you are using automatic module loading, ensure the search path and filters are correct. 

下面是導致此異常的測試用例:

[TestInitialize] 
public void Initialize() 
{ 
    BootStrapper.RegisterTypes(); 
} 

[TestMethod] 
public void Can_Create_Alert_Management_Object() 
{ 
    IAlertManagement alertManagementService = BootStrapper.Kernel.Get<IAlertManagement>(); 

    Assert.IsNotNull(alertManagementService); 
} 

//This is the code that gets called in [TestInitialize] 
public static void RegisterTypes() 
{ 
    if (!initialized) 
    { 
     Kernel.Bind(scanner => scanner.FromAssembliesMatching("MyCompany.MyProduct.*") 
            .SelectAllClasses() 
            .BindDefaultInterface()); 

     Kernel.Unbind(typeof(IWcfServiceClient<>)); 
     Kernel.Bind(typeof(IWcfServiceClient<>)).ToMethod(ctx => 
        (ctx.Kernel.Get(typeof(WcfServiceClientProvider<>).MakeGenericType(ctx.GenericArguments)) as IProvider).Create(ctx)); 
    } 

    initialized = true; 
} 

上述錯誤中的一個發生我的單元測試我們的構建服務器,但不在我的開發機器上。我有7個其他測試幾乎完全相同,通過構建服務器和我的開發機器上的,但這是唯一的測試失敗。

的IAlertManagement接口從DLL來稱爲核心和具體類型是從另一個DLL來稱爲AlertManagement。我的單元測試項目中包含核心 dll和AlertManagement dll作爲項目參考。我有7或8個與這種情況相同的其他測試,但這是唯一的失敗。

任何想法都是值得讚賞的。

回答

0

我最終通過在單元測試項目中添加對解析類型的具體引用來解決此問題。僅僅添加項目引用是不夠的。這是我如何做到這一點:

[TestClass] 
public class AssemblyInitialize 
{ 
    /// <summary> 
    /// Method which gets executed once per unit test session. The purpose of this method is to reference any loosely coupled 
    /// assemblies so that they get included in the unit test session. If no code actually references a given assembly, even if its 
    /// technically a project reference, it will not be copied to the test output folder. 
    /// </summary> 
    [AssemblyInitialize] 
    public static void InitializeReferencedAssemblies(TestContext context) 
    { 
     List<Type> looselyCoupledTypes = new List<Type> 
             { 
              typeof(AlertManagement), 
              typeof(Naming), 
             }; 

     looselyCoupledTypes.ForEach(x => Console.WriteLine("Including loosely coupled assembly: {0}", 
                  x.Assembly.FullName)); 
    } 
} 
0
  1. ,我會檢查的第一件事是確保包含的IAlertManagement實施DLL是越來越拷貝到正確的目錄生成服務器,以便測試看到它。

  2. 另一個嘗試的方法是將內核加載代碼移動到ClassInitialize函數而不是TestInitialize,以查看是否存在某種競爭條件或其他相關事件。我發現構建服務器上的隨機錯誤是由於對象按照不同的順序處理或比正常情況下發生的時間更早(涉及Rx,TPL和我的案例中未發現的異常)。可能會有更多的測試在構建服務器上並行運行,而不是在桌面上運行。

  3. 或者這可能部分是由於服務器可能使用Server GC這一事實。我不知道是否強制它使用Workstation GC會有所幫助,但它可能值得一試。

+0

我確實在構建服務器上的drop文件夾中看到包含'IAlertManagement'的dll。我也嘗試切換單元測試類來使用'[ClassInitialize]'而不是'[TestInitialize]',但它似乎沒有幫助。我還沒有探索過選項3. – 2012-09-20 19:14:22

+0

只是爲了進行測試,請嘗試將具體的AlertManagement放入您正在看到的程序集中,例如Core。例如,添加一個類的存根。然後你會知道它是否找不到該文件或者有其他的東西。 – 2012-09-21 17:10:17

1

發生此錯誤是因爲IAlertManagement未綁定任何具體類。 嘗試手動綁定IAlertManagement

public static void RegisterTypes() 
{ 
    if (!initialized) 
    { 
     Kernel.Bind(scanner => scanner.FromAssembliesMatching("MyCompany.MyProduct.*") 
           .SelectAllClasses() 
           .BindDefaultInterface()); 


     //Try to add following line 
     Kernel.Bind<IAlertManagement>().To<ConcreteImplementationOfIAlertManagement>(); 

     Kernel.Unbind(typeof(IWcfServiceClient<>)); 
     Kernel.Bind(typeof(IWcfServiceClient<>)).ToMethod(ctx => (ctx.Kernel.Get(typeof(WcfServiceClientProvider<>).MakeGenericType(ctx.GenericArguments)) as IProvider).Create(ctx)); 
    } 

    initialized = true; 
} 
+0

這可能會工作,但這是我想擺脫首位。我不想添加對具體類的所有dll的引用。 – 2012-09-20 12:00:01