Ninject ActivationException:激活IAlertManagement时出错

9
我收到了以下错误信息:
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接口来自名为“Core”的dll,具体类型来自另一个名为“AlertManagement”的dll。我在单元测试项目中包含了“Core”和“AlertManagement”两个dll作为项目引用。我有7或8个其他相同情况的测试,但这是唯一失败的测试。
任何想法将不胜感激。
3个回答

1

我最终通过在我的单元测试项目中添加具体的解析类型引用来解决了这个问题。仅添加项目引用是不够的。以下是我的做法:

[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));
    }
}

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;
}

可能会有作用,但这正是我一开始想要避免的。我不想为所有具体类所在的dll添加引用。 - Cole W

0
  1. 我首先要检查的是确保包含 IAlertManagement 实现的 DLL 被复制到构建服务器上的正确目录,以便测试可以看到它。

  2. 另一个尝试的方法是将内核加载代码移动到 ClassInitialize 函数中,而不是 TestInitialize,只是为了查看是否存在某种竞争条件或其他相关问题。我曾经在构建服务器上看到过由于对象被以不同的顺序或比通常发生得更早地处理(涉及 Rx、TPL 和未观察到的异常),导致随机错误的情况。可能是因为在构建服务器上运行的测试比在桌面上运行的测试更多。

  3. 或者部分原因可能是由于服务器可能正在使用 Server GC。我不知道强制它使用 Workstation GC 是否有帮助,但这可能值得一试。


我在构建服务器的放置文件夹中看到了包含“IAlertManagement”的dll。我还尝试将单元测试类切换为使用[ClassInitialize]而不是[TestInitialize],但似乎没有帮助。我还没有探索第三个选项。 - Cole W
只是为了测试,尝试将具体的AlertManagement放入一个你知道正在被查看的程序集中,比如Core。例如,只需添加该类的存根。然后你就会知道它是否无法找到文件或者还有其他问题。 - Austin Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接