3

I've been trying to get Ninject.Extensions.Conventions for (Ninject 3+) working, with no luck. I boiled it down to a found sample console app, and I can't even get that going. Here's what I have:

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

I've also tried various combos of FromAssembliesMatching, SelectAllTypes, BindDefaultInterfaces, etc. Everything throws the Error activating . No matching bindings are available, and the type is not self-bindable.

Just for sanity, if I do a manual binding with:

kernel.Bind<IConsoleOutput>().To<ConsoleOutput>();

Everything works just fine. So clearly I'm just missing something.

Michael Cook
  • 1,676
  • 2
  • 26
  • 47
  • 2
    Perhaps because you're classes and interface are internal. – sam Sep 13 '13 at 20:14
  • I don't think that's the issue, I have the exact same issue on my primary app, which is more standard in it's construction. – Michael Cook Sep 16 '13 at 18:05
  • Just for debugging, you might want to specify a binding generator (+ implement it) then set a break point inside the binding generator to see which "classes", or what ever you specify, are found. We are using ninject 3 and conventions are working just fine. – BatteryBackupUnit Sep 18 '13 at 14:22

1 Answers1

8

It is caused, as sam suggested, by the types not being public. They are inner types of the non-public "Program" class.

Make Program public or add .IncludingNonPublicTypes():

kernel.Bind(x => x
    .FromThisAssembly()
    .IncludingNonPublicTypes()
    .SelectAllClasses()
    .BindAllInterfaces());

(I have verified that either works, and your code doesn't).

And here is your official source: https://github.com/ninject/ninject.extensions.conventions/blob/master/src/Ninject.Extensions.Conventions.Test/IntegrationTests/NonPublicTypesTests.cs

Note: In older versions of Ninject this method was called IncludeNonePublicTypes (None vs Non).

BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • 2
    The method should be spelled IncludingNonPublicTypes() notice the e is gone after Non – reggaeguitar Feb 04 '14 at 23:59
  • 1
    You are correct. However the ninject interface spells it this way. See https://github.com/ninject/ninject.extensions.conventions/blob/master/src/Ninject.Extensions.Conventions/Syntax/IIncludingNonePublicTypesSyntax.cs – BatteryBackupUnit Feb 05 '14 at 12:42
  • I was hoping the Ninject designers would see my comment and change it. I guess it's not worth making a breaking change just so something is spelled correctly though. – reggaeguitar Feb 05 '14 at 16:26
  • They ought to correct it, and leave the old one around for compatibility purposes, and throw a `deprecated` attribute on the incorrect one. – Doctor Blue Jun 17 '14 at 18:33