ung*_*ood 26
虽然Sean Chambers的解决方案适用于您控制插件的情况,但是如果插件可能由第三方开发并且您不希望它们必须依赖于编写ninject模块,则它不起作用.
对于Ninject 的约定扩展,这很容易做到:
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Scan(scanner => {
scanner.FromAssembliesInPath(@"Path\To\Plugins");
scanner.AutoLoadModules();
scanner.WhereTypeInheritsFrom<IPlugin>();
scanner.BindWith<PluginBindingGenerator<IPlugin>>();
});
return kernel;
}
private class PluginBindingGenerator<TPluginInterface> : IBindingGenerator
{
private readonly Type pluginInterfaceType = typeof (TPluginInterface);
public void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel)
{
if(!pluginInterfaceType.IsAssignableFrom(type))
return;
if (type.IsAbstract || type.IsInterface)
return;
kernel.Bind(pluginInterfaceType).To(type);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用所有加载的插件kernel.GetAll<IPlugin>()
.
这种方法的优点是:
Sea*_*ers 12
这个问题适用于我在此提供的相同答案:NInject可以按需加载模块/组件吗?
我很确定这就是你要找的东西:
var kernel = new StandardKernel();
kernel.Load( Assembly.Load("yourpath_to_assembly.dll");
Run Code Online (Sandbox Code Playgroud)
如果在Ninject.dll中查看带有反射器的KernelBase,您将看到此调用将递归加载已加载程序集中的所有模块(Load方法采用IEnumerable)
public void Load(IEnumerable<Assembly> assemblies)
{
foreach (Assembly assembly in assemblies)
{
this.Load(assembly.GetNinjectModules());
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这种情况,我不希望直接汇编引用会经常更改的内容,我可以换出程序集为应用程序提供不同的模型(授予我适当的测试)
小智 11
扩展@ungood的良好答案,基于v.2,与Ninject的v.3(目前在RC3上),它可以变得更容易.你不再需要任何IPluginGenerator,只需写:
var kernel = new StandardKernel();
kernel.Bind(scanner => scanner.FromAssembliesInPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.SelectAllClasses()
.InheritedFrom<IPlugin>()
.BindToAllInterfaces());
Run Code Online (Sandbox Code Playgroud)
请注意我正在寻找实现IPlugin的插件(将你的界面放在这里)在应用程序的相同路径中.
您可以使用普通的 C# 反射轻松完成此操作,不需要任何额外的技术。
网上有很多例子,例如 http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
一般来说,在主应用程序中,您需要加载实现插件的程序集,例如:
ass = Assembly.Load(name);
Run Code Online (Sandbox Code Playgroud)
然后您需要创建插件的实例。如果您知道类的名称,它将如下所示:
ObjType = ass.GetType(typename);
IPlugin plugin = (IPlugin)Activator.CreateInstance(ObjType);
Run Code Online (Sandbox Code Playgroud)
然后你就可以使用它了。
归档时间: |
|
查看次数: |
13279 次 |
最近记录: |