Ninject: Can modules be loaded that are declared as internal
Asked Answered
P

3

7

Is it at all possible to configure Ninject to load modules that have been declared as internal?

I have tried configuring InternalVisibleTo for the Ninject assembly, but this does not help.

I can of course make the modules public, but really they should be internal.

Peroxide answered 23/6, 2011 at 13:29 Comment(0)
S
8

Internally KernalBase.Load(IEnumerable<Assembly assemblies) uses the GetExportedTypes() which only returns public types.

However, you could write your own "NinjectModule scanner".

public static class NinjectModuleScanner
{
    public static IEnumerable<INinjectModule> 
        GetNinjectModules(IEnumerable<Assembly assemblies)
    {
        return assemblies.SelectMany(assembly => assembly.GetNinjectModules());
    }
}

public static class AssemblyExtensions
{
    public static IEnumerable<INinjectModule> 
        GetNinjectModules(this Assembly assembly)
    {
        return assembly.GetTypes()
            .Where(IsLoadableModule)
            .Select(type => Activator.CreateInstance(type) as INinjectModule);
    }

    private static bool IsLoadableModule(Type type)
    {
        return typeof(INinjectModule).IsAssignableFrom(type)
            && !type.IsAbstract
            && !type.IsInterface
            && type.GetConstructor(Type.EmptyTypes) != null;
    }
}

Then you could do the following.

var modules = NinjectModuleScanner.GetNinjectModules(assemblies).ToArray();
var kernel = new StandardKernel();

This solution has not been tested though.

Stork answered 23/6, 2011 at 13:49 Comment(2)
Works very well, hadn't thought of approaching it like that as I was looking for something built in. Thanks.Peroxide
just the idea of DI is horrible and grotesque, this make it worse to another whole level.Weisshorn
G
5

You can configure Ninject to inject internal classes using the InjectNonPublic property from NinjectSettings class. You have to pass it as an argument to the StandardKernel constructor:

var settings = new NinjectSettings
{
    InjectNonPublic = true
};
kernel = new StandardKernel(settings);
Gallard answered 19/11, 2015 at 4:8 Comment(0)
S
0
var kernel = new StandardKernel();

var modules = Assembly
                    .GetExecutingAssembly()
                    .DefinedTypes
                    .Where(typeof(INinjectModule).IsAssignableFrom)
                    .Select(Activator.CreateInstance)
                    .Cast<INinjectModule>();

kernel.Load(modules);
Swann answered 23/6, 2017 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.