卸载 Ninject 加载的程序集
Unload Assemblies loaded by Ninject
我使用 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 无法卸载程序集。
您查看 AppDomains 是正确的。您无法卸载类型或程序集,因此您的 Kernel.Release
不会从您的应用程序中删除类型,您的应用程序根本不会引用它。
您只能卸载一个 AppDomain。使用这种方法,您必须意识到您正在跨越边界。您可以通过引用 MarshalByRefObjects which gives you a reference to the object in another domain. If you can serialize (serialized) 您的对象来编组您的对象,您将 运行 遇到与现在 运行 相同的问题,因为对象将在主域中反序列化。因此,不要跨域传递任何您不想锁定到主机 AppDomain 中的对象。
您需要提供主机 AppDomain 和托管 AppDomain 都知道的接口。
我建议您查看 MS Add-In Framework(MAF)。
我使用 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 无法卸载程序集。
您查看 AppDomains 是正确的。您无法卸载类型或程序集,因此您的 Kernel.Release
不会从您的应用程序中删除类型,您的应用程序根本不会引用它。
您只能卸载一个 AppDomain。使用这种方法,您必须意识到您正在跨越边界。您可以通过引用 MarshalByRefObjects which gives you a reference to the object in another domain. If you can serialize (serialized) 您的对象来编组您的对象,您将 运行 遇到与现在 运行 相同的问题,因为对象将在主域中反序列化。因此,不要跨域传递任何您不想锁定到主机 AppDomain 中的对象。
您需要提供主机 AppDomain 和托管 AppDomain 都知道的接口。
我建议您查看 MS Add-In Framework(MAF)。