AppDomain的阴影复制不工作(原组件锁定)组件、阴影、工作、AppDomain

2023-09-04 00:45:56 作者:勋你一鹿奶茶

下面是我用探测可用的插件列表的小类:

Here's a small class I'm using to probe for a list of available plugins:

internal static class PluginDirectoryLoader
{
    public static PluginInfo[] ListPlugins(string path)
    {
        var name = Path.GetFileName(path);
        var setup = new AppDomainSetup
        {
            ApplicationBase = path,
            ShadowCopyFiles = "true"
        };
        var appdomain = AppDomain.CreateDomain("PluginDirectoryLoader." + name, null, setup);
        var exts = (IServerExtensionDiscovery)appdomain.CreateInstanceAndUnwrap("ServerX.Common", "ServerX.Common.ServerExtensionDiscovery");
        PluginInfo[] plugins = null;
        try
        {
            plugins = exts.ListPlugins(); // <-- BREAK HERE
        }
        catch
        {
            // to do
        }
        finally
        {
            AppDomain.Unload(appdomain);
        }
        return plugins ?? new PluginInfo[0];
    }
}

路径参数指向包含插件组件来加载一个子目录。这个想法是使用阴影复制一个单独的AppDomain启动加载它们。

The path parameter points to a subdirectory containing the plugin assemblies to load. The idea is to load them using a separate AppDomain with shadow copying enabled.

在这个的情况下,影复制是不是真的有必要看到,因为在AppDomain迅速卸载,但是当我实际加载的插件在code中的下一个块,我打算写的,我想用阴影复制这样的二进制文件可以动态更新。我已经启用的影子复制在这个类的一个测试,以确保我这样做是正确的。

In this case, shadow copying isn't really necessary seeing as the AppDomain is unloaded quickly, but when I actually load the plugins in the next block of code I intend to write, I want to use shadow copying so the binaries can be updated on the fly. I have enabled shadow copying in this class as a test to make sure I'm doing it right.

显然,我不这样做是正确的,因为当我在注释行的code样品(即插件= exts.ListPlugins())时,原来的插件组件锁定由应用!

Apparently I'm not doing it right because when I break in the debugger on the commented line in the code sample (i.e. plugins = exts.ListPlugins()), the original plugin assemblies are locked by the application!

看到因为我指定的AppDomain中加载的程序集应影子复制,为什么会被锁定的应用程序?

Seeing as I'm specifying that assemblies loaded by the AppDomain should be shadow copied, why are they being locked by the application?

推荐答案

我想它了。有一个属性我错过了 AppDomainSetup 。该物业是 ShadowCopyDirectories

I figured it out. There was one property I missed in AppDomainSetup. The property was ShadowCopyDirectories.

var setup = new AppDomainSetup
{
    ApplicationBase = path,
    ShadowCopyFiles = "true",
    ShadowCopyDirectories = path
};

当在我的问题中提到的断行,我现在可以删除该插件组件,即使没有卸载的AppDomain。

When breaking on the line mentioned in my question, I can now delete the plugin assemblies even without unloading the AppDomain.