无法让Ninject.Extensions.Conventions正常工作

3

我一直在尝试让Ninject.Extensions.Conventions(适用于Ninject 3+)起作用,可是一直没有成功。 我将其简化为一个已找到的示例控制台应用程序,但是我甚至无法启动它。这是我的代码:

 class Program
    {
        static void Main(string[] args)
        {
            var kernel = new StandardKernel();
            kernel.Bind(x => x
               .FromThisAssembly()
               .SelectAllClasses()
               .BindAllInterfaces());

            var output = kernel.Get<IConsoleOutput>();
            output.HelloWorld();

            var service = kernel.Get<Service>();
            service.OutputToConsole();

            Console.ReadLine();
        }

        public interface IConsoleOutput
        {
            void HelloWorld();
        }

        public class ConsoleOutput : IConsoleOutput
        {
            public void HelloWorld()
            {
                Console.WriteLine("Hello world!");
            }
        }

        public class Service
        {
            private readonly IConsoleOutput _output;
            public Service(IConsoleOutput output)
            {
                _output = output;
            }

            public void OutputToConsole()
            {
                _output.HelloWorld();
            }
        }
    }

我还尝试过各种组合使用FromAssembliesMatchingSelectAllTypesBindDefaultInterfaces等方法,但是都会抛出“Error activating . No matching bindings are available, and the type is not self-bindable.”的错误提示。
为了保证正确性,如果我手动绑定如下内容:
kernel.Bind<IConsoleOutput>().To<ConsoleOutput>();

一切都很好。显然我只是漏了什么东西。


2
可能是因为你的类和接口是内部的。 - sam
我认为这不是问题所在,我的主要应用程序也有完全相同的问题,它的构建更加标准化。 - Michael Cook
仅用于调试,您可能希望指定一个绑定生成器(+实现它),然后在绑定生成器内设置断点,以查看找到哪些“类”或您指定的任何内容。 我们正在使用Ninject 3,约定正常工作。 - BatteryBackupUnit
1个回答

8
这是由于类型不是公共的所导致的,正如Sam所建议的那样。它们是非公共的“Program”类的内部类型。
使Program公共或添加.IncludingNonPublicTypes():
kernel.Bind(x => x
    .FromThisAssembly()
    .IncludingNonPublicTypes()
    .SelectAllClasses()
    .BindAllInterfaces());

我已经验证了两者都可以,而且你的代码不行。

这是您的官方来源: https://github.com/ninject/ninject.extensions.conventions/blob/master/src/Ninject.Extensions.Conventions.Test/IntegrationTests/NonPublicTypesTests.cs

注意:在旧版本的Ninject中,此方法称为IncludeNonePublicTypes(None与Non之间有区别)。


2
该方法应该拼写为IncludingNonPublicTypes(),请注意在Non之后没有e。 - reggaeguitar
1
你是正确的。然而,Ninject接口就是这样拼写的。请参见:https://github.com/ninject/ninject.extensions.conventions/blob/master/src/Ninject.Extensions.Conventions/Syntax/IIncludingNonePublicTypesSyntax.cs - BatteryBackupUnit
我本来希望Ninject的设计者能看到我的评论并进行更改。不过,为了拼写正确而进行重大更改似乎并不值得。 - reggaeguitar
他们应该纠正它,保留旧版本以确保兼容性,并在错误版本上添加“已弃用”属性。 - Doctor Blue

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