Ninject:是否可以加载声明为内部的模块

7

是否有可能配置Ninject以加载已声明为internal的模块?

我尝试为Ninject程序集配置InternalVisibleTo,但这并没有帮助。

当然,我可以将模块设置为public,但它们应该是internal

3个回答

8

在内部,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();

尽管这个解决方案还没有经过测试。


运行得很好,我没有想到可以这样实现,因为我一直在寻找内置的方法。谢谢。 - Tim Lloyd
仅翻译文本内容:仅依赖注入的想法就是可怕和丑陋的,这使得它变得更加糟糕到另一个整体水平。 - Liquid Core

5
你可以使用 NinjectSettings 类的 InjectNonPublic 属性来配置 Ninject 以注入内部类。你需要将其作为参数传递给 StandardKernel 构造函数:
var settings = new NinjectSettings
{
    InjectNonPublic = true
};
kernel = new StandardKernel(settings);

0
var kernel = new StandardKernel();

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

kernel.Load(modules);

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