【问题标题】:Resolving Ninject version conflicts in a plugin architecture解决插件架构中的 Ninject 版本冲突
【发布时间】: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 引用正在泄漏(必然)并且现在开始导致版本冲突错误。 有没有办法可以重构这个架构来避免这个问题,并且仍然允许我的插件指定他们自己的依赖注入绑定?

【问题讨论】:

    标签: c# plugins ninject


    【解决方案1】:

    当插件需要使用与程序使用的相同版本的 ninject,但依赖于不同版本的功能时,.. 那永远都行不通了。

    我们可以改变两件事

    • 确保插件始终使用与程序相同的版本构建
    • 允许插件使用它喜欢的任何容器

    可以通过实现类似于 ninject 的child kernel extension 的东西来消除使用相同 IoC 版本的限制:

    应用程序创建并使用主内核。 每个插件都使用自己的 IoC。 Ninject、Unity、Autofac,应有尽有。 IoC 以某种方式进行了扩展,当自身无法满足请求时,它会将请求传递到应用程序的主内核。

    您需要提供一个接口来访问主内核。您还需要容器特定的“子内核”扩展实现,每当 IoC 更新时可能需要更新这些实现。

    子内核实现其实很小,见https://github.com/ninject/ninject.extensions.childkernel/blob/master/src/Ninject.Extensions.ChildKernel/ChildKernel.cs

    【讨论】:

    • 子内核看起来很有希望 - 感谢领导。
    猜你喜欢
    • 1970-01-01
    • 2015-07-02
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2019-01-10
    相关资源
    最近更新 更多