Ninject -> 扫描程序集以匹配接口并作为模块加载

6
在较早的Ninject.Extensions.Conventions版本中,扫描目录以查找程序集、按接口过滤类,然后加载所有包含ninject模块的步骤非常简单。
kernel.Scan(scanner =>
    scanner.FromAssembliesInPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
    scanner.AutoLoadModules();
    scanner.WhereTypeInheritsFrom<IPlugin>());

public class MyPlugin : NinjectModule, IPlugin {

     public override void Load() {
          Bind<IRepositoryFromPluginHost>().To<MyPluginImpl>().Named("special");
     }
}

然而,最近我更新到最新版本后,所有的东西似乎都消失了,我无法:

  1. 自动加载模块
  2. 按接口过滤类型

有人有解决方案吗?

2个回答

4

仍有https://github.com/ninject/ninject.extensions.conventions扩展。 然而,接口已经改变,变成了以下内容:

kernel.Bind(x =>
{
    x.FromAssembliesInPath("somepath")
     .IncludingNonePublicTypes()
     .SelectAllClasses()
     .InheritedFrom<IPlugin>()
     .BindDefaultInterface() // Binds the default interface to them;
});

更新: 你可以使用约定扩展(如上所示)将所有IPlugin绑定到IPlugin,然后执行以下操作:
var plugins = IResolutionRoot.GetAll<IPlugin>();
kernel.Load(plugins);

1
是的,但那不完全是我想要的。你的例子从某个路径中加载所有继承自特定接口的程序集中的所有类,并绑定默认接口。然而,我想做的只是从包含绑定指令的程序集中作为插件加载Ninject模块。 - Acrotygma
很抱歉我弄错了。我会研究是否有某种方法可以实现这一点。默认情况下,Ninject StandardKernel仍会自动加载以´Ninject.Extensions.´开头的程序集中的所有´IModule´,因此代码可能是可访问的。 - BatteryBackupUnit
抱歉让你久等了。我已经更新答案,展示了我们以前是如何处理插件的。如果你不想要额外的“IPlugin”绑定浮动在周围,我会选择@Eric的答案。 - BatteryBackupUnit
在ninject.extensions.conventions的v3.2.0.0版本中,应该使用"IncludingNonePublicTypes()"而不是"IncludeNonPublicTypes()"。 - Whit Waldo
@Xaniff:是的,没错。虽然语法不正确,但我已经正确引用了代码。这里没有需要我编辑的内容。 - BatteryBackupUnit
显示剩余5条评论

1
也许比较麻烦,但是类似下面这样的方法可以获取一个由NinjectModule派生的类型列表。
var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
List<Type> types = new List<Type>();
foreach (var assembly in assemblies) 
{
    types.AddRange(GetModules(assembly)); 
}


    IEnumerable<Type> GetModules(Assembly assembly)
    {
         assembly.GetTypes()
              .Where(t => t.BaseType == typeof(NinjectModule));       
    }

要加载您的模块,请尝试以下操作。

(Activator.CreateInstance(type) as NinjectModule).Load();


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