Ninject: Can modules be loaded that are declared as internal

。_饼干妹妹 提交于 2019-12-04 04:06:15
mrydengren

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.

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);
var kernel = new StandardKernel();

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

kernel.Load(modules);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!