C# 如何为 .NET 应用程序域重新加载程序集?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1024072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:46:40  来源:igfitidea点击:

How to reload an assembly for a .NET Application Domain?

c#.netappdomain

提问by Mr. T.

We are loading an assembly (a DLL) which reads a configuration file. We need to change the configuration file and then re-load the assembly. We see that after loading the assembly the 2nd time, there is no change in the configuration. Anyone see what is wrong here? We left out the details of reading in the configuration file.

我们正在加载一个程序集(一个 DLL),它读取一个配置文件。我们需要更改配置文件,然后重新加载程序集。我们看到第二次加载程序集后,配置没有变化。有人看到这里有什么问题吗?我们省略了在配置文件中读取的细节。

AppDomain subDomain;
string assemblyName = "mycli";
string DomainName = "subdomain"; 
Type myType;
Object myObject;

// Load Application domain + Assembly
subDomain = AppDomain.CreateDomain( DomainName,
                                    null,
                                    AppDomain.CurrentDomain.BaseDirectory,
                                    "",
                                    false);

myType = myAssembly.GetType(assemblyName + ".mycli");
myObject = myAssembly.CreateInstance(assemblyName + ".mycli", false, BindingFlags.CreateInstance, null, Params, null, null);

// Invoke Assembly
object[] Params = new object[1];
Params[0] = value;
myType.InvokeMember("myMethod", BindingFlags.InvokeMethod, null, myObject, Params);

// unload Application Domain
AppDomain.Unload(subDomain);

// Modify configuration file: when the assembly loads, this configuration file is read in

// ReLoad Application domain + Assembly
// we should now see the changes made in the configuration file mentioned above

回答by John Saunders

I believe the only way to do this is to start a new AppDomain and unload the original one. This is how ASP.NET has always handled changes to web.config.

我相信做到这一点的唯一方法是启动一个新的 AppDomain 并卸载原来的 AppDomain。这就是 ASP.NET 始终处理 web.config 更改的方式。

回答by Sean

You can't unload an assembly once it's been loaded. However, you can unload an AppDomain, so your best bet would be to load the logic into a separate AppDomain and then when you want to reload the assembly you'll have to unload the AppDomain and then reload it.

一旦加载了程序集,就无法卸载它。但是,您可以卸载 AppDomain,因此最好的办法是将逻辑加载到单独的 AppDomain 中,然后当您想要重新加载程序集时,您必须卸载 AppDomain,然后重新加载它。

回答by Richard Anthony Hein

If you are just changing some sections you can use ConfigurationManager.Refresh("sectionName") to force a re-read from disk.

如果您只是更改某些部分,则可以使用 ConfigurationManager.Refresh("sectionName") 强制从磁盘重新读取。

static void Main(string[] args)
    {
        var data = new Data();
        var list = new List<Parent>();
        list.Add(new Parent().Set(data));

        var configValue = ConfigurationManager.AppSettings["TestKey"];
        Console.WriteLine(configValue);

        Console.WriteLine("Update the config file ...");
        Console.ReadKey();

        configValue = ConfigurationManager.AppSettings["TestKey"];
        Console.WriteLine("Before refresh: {0}", configValue);

        ConfigurationManager.RefreshSection("appSettings");

        configValue = ConfigurationManager.AppSettings["TestKey"];
        Console.WriteLine("After refresh: {0}", configValue);

        Console.ReadKey();
    }

(Note that you have to change the application.vshost.exe.config file if you are using the VS hosting process, when testing this.)

(请注意,如果您正在使用 VS 托管进程,则在测试时必须更改 application.vshost.exe.config 文件。)