卸载由Ninject加载的程序集

本文关键字:程序集 加载 Ninject 卸载 | 更新日期: 2023-09-27 18:00:54

我用Ninject构建了一个插件系统。我这样加载插件:

private void LoadPlugIns()
{
    lock (_syncRoot)
    {
    Kernel.Bind(x => x.FromAssembliesInPath(AppDomain.CurrentDomain.BaseDirectory)
        .SelectAllClasses().InheritedFrom<IRenderPlugIn>()
        .BindAllInterfaces()
        .Configure(b => b.InSingletonScope()));
    RenderPlugins = Kernel.GetAll<IRenderPlugIn>();
    if (RenderPlugins != null && RenderPlugins.Count() > 0)
        Logger.Info("{0} Render-Plugins geladen.", RenderPlugins.Count());
    else
        Logger.Warn("Keine Render-Plugins geladen.");
    }
}

现在我想能够在应用程序运行时更新插件,我正在卸载所有插件,如下所示:

private void UnloadPlugIns()
{
    lock (_syncRoot)
    {
        Logger.Trace("Entlade Render-Plugins.");
        var plugins = _renderPlugins;
        RenderPlugins = null;
        Kernel.Unbind<IRenderPlugIn>();
        if (plugins != null)
            foreach (var plugin in plugins)
                Kernel.Release(plugin);
        else
            Logger.Warn("Es waren keine Render-Plugins geladen.");
        Logger.Info("Alle Render-Plugins entladen.");
    }
}

我的问题是插件程序集仍然被进程锁定,因此我无法删除或覆盖它们。

我读过一些关于AppDomains和ShadowCopyFiles的东西,我认为这可能会有所帮助。但是,当我的插件管理器使用AppDomain时,我必须处理远程处理对象的有限寿命,这会引起很多头痛。

有什么方法可以用Ninject做到这一点吗?

卸载由Ninject加载的程序集

[Edit]Ninject无法卸载程序集。

您查看AppDomains是正确的。您无法卸载类型或程序集,因此Kernel.Release不会从应用程序中删除类型,您的应用程序只是不引用它。

您只能卸载AppDomain。通过这种方法,你必须意识到你正在跨越一个边界。您可以通过引用MarshalByRefObjects封送您的对象,该对象为您提供了对另一个域中对象的引用。如果您可以序列化(序列化(对象,您将遇到与现在遇到的问题相同的问题,因为对象将在主域中进行反序列化。因此,不要在域之间传递任何您不想锁定到主机AppDomain中的对象。

您需要提供一个主机AppDomain和主机AppDomain都知道的接口。

我建议您查看MS插件框架(MAF(。