Ninject: Могут ли быть загружены модули, которые объявлены как внутренние - PullRequest
7 голосов
/ 23 июня 2011

Можно ли вообще настроить Ninject для загрузки модулей, которые были объявлены как internal?

Я попытался настроить InternalVisibleTo для сборки Ninject, но это не помогает.

Конечно, я могу сделать модули public, но на самом деле они должны быть internal.

Ответы [ 3 ]

7 голосов
/ 23 июня 2011

Внутренне KernalBase.Load(IEnumerable<Assembly assemblies) использует GetExportedTypes(), который возвращает только открытые типы.

Однако вы можете написать свой собственный "сканер NinjectModule".

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

Тогда вы можете сделать следующее.

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

Это решение не было проверено, хотя.

5 голосов
/ 19 ноября 2015

Вы можете настроить Ninject для внедрения внутренних классов, используя свойство InjectNonPublic из класса NinjectSettings. Вы должны передать его в качестве аргумента конструктору StandardKernel:

var settings = new NinjectSettings
{
    InjectNonPublic = true
};
kernel = new StandardKernel(settings);
0 голосов
/ 23 июня 2017
var kernel = new StandardKernel();

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

kernel.Load(modules);
...