【发布时间】:2014-06-12 14:22:37
【问题描述】:
我有一个支持插件的应用程序。这些插件是加载到独立应用程序域中的 DLL 集。我的主要应用程序在这些域中(通过 Ninject.Extensions.Conventions)查找继承自 IPlugin 的类,并按以下方式将每个类绑定到它们的具体插件实现:
var kernel = new StandardKernel();
kernel.Bind(scanner => scanner.From(pluginAssemblies).SelectAllClasses()
.InheritedFrom<IPlugin>().BindWith<CustomBindingGenerator<IPlugin>>());
//CustomBindingGenerator
public class CustomBindingGenerator<TInterface> : IBindingGenerator
{
public static readonly string MetadataKey = "PluginKey";
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
Type interfaceType = typeof(TInterface);
if (!interfaceType.IsAssignableFrom(type))
yield return null;
yield return (IBindingWhenInNamedWithOrOnSyntax<object>)bindingRoot.Bind(interfaceType).To(type).WithMetadata(MetadataKey, type.FullName);
}
}
这一切都很好 - 插件被加载,然后可以根据需要启动和执行。当我尝试为插件本身提供依赖注入功能时,我的问题就开始了,这样插件就可以对其特定的应用程序依赖项使用构造函数注入。我让每个插件都定义了一个IDependencySpecification,它传递了对同一内核的引用,该内核保存了程序集中所有插件的绑定(即上面的相同kernel):
public class MyPluginDependencySpecification : IDependencySpecification
{
public void SetupDependencies(IKernel kernel)
{
kernel.Bind<IMyService>().To<MyService>();
....
}
}
这很好用——只要主应用程序使用的 Ninject 版本与插件使用的 Ninject 版本相同。一些较新的插件开始依赖于需要较新版本的 Ninject 的库,当尝试加载此 IDependencySpecification 时,我的主应用程序会抛出一个错误,指出它没有实现 SetupDependencies 方法。
总而言之,尽管我尝试以几乎所有方式(通过应用程序域等)将我的插件与我的应用程序隔离开来,但这个 Ninject 引用正在泄漏(必然)并且现在开始导致版本冲突错误。 有没有办法可以重构这个架构来避免这个问题,并且仍然允许我的插件指定他们自己的依赖注入绑定?
【问题讨论】: