使用AppDomain进行动态加载和卸载dll

Posted 狂乱贵公子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用AppDomain进行动态加载和卸载dll相关的知识,希望对你有一定的参考价值。

加载dll最简单的写法

Assembly.Load("<dll路径>")

  

但这样写这个dll就被程序占用不可删除,即不可以卸载。

 

通过AppDomain加代理的方式进行加载则可以实现卸载,从而实现程序不被占用并被删除。

 

第一步,创建AssemblyProxy类

public class AssemblyProxy : MarshalByRefObject
{
        private Assembly assembly;

        public void LoadAssembly(string fullName)
        {
            assembly = Assembly.LoadFrom(fullName);
        }/// <summary>
        /// 开放委托,可使用Assembly操作
        /// </summary>
        /// <param name="action"></param>
        public T Work<T>(Func<Assembly, T> action)
        {
            return action.Invoke(assembly);
        }
}

 

AssemblyProxy类将运行在子AppDomain中,通过操作AssemblyProxy类进行反射加载的DLL。保证AppDomain.CurrentDomain和子AppDomain隔离,最后卸载子AppDomain就实现了动态加载和卸载dll的目标。

 

第二步,实现AssemblyLoader类

 

public class AssemblyLoader
{
        private AppDomain appDomain;

        public AssemblyProxy Proxy;

        public AssemblyLoader()
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = "Child";
            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private");
            setup.CachePath = setup.ApplicationBase;
            setup.ShadowCopyFiles = "true";
            setup.ShadowCopyDirectories = setup.ApplicationBase;

            appDomain = AppDomain.CreateDomain("ChildDomain", null, setup);
            string name = Assembly.GetExecutingAssembly().GetName().FullName;

       // 从子类AppDomain中反射创建AssemblyProxys实例 Proxy
= (AssemblyProxy)appDomain.CreateInstanceAndUnwrap(name, typeof(AssemblyProxy).FullName); } public void LoadAssembly(string fullName) { Proxy.LoadAssembly(fullName); } public void Unload() { AppDomain.Unload(appDomain); appDomain = null; } }

 

接着就可以使用了

 

var loader = new AssemblyLoader();
loader.LoadAssembly(path);

var version = loader.Proxy.Work(assembly =>
{
     return assembly.GetName().Version.ToString();
});

loader.Unload();

 

以上是关于使用AppDomain进行动态加载和卸载dll的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain 详解二-C#中动态加载和卸载DLL

AppDomain 卷影副本 - 加载/卸载动态加载的 Dll

将 c# 程序集动态加载和卸载到 appdomain

卸载后 AppDomain 和使用的 DLL 的问题

C#动态加载dll 时程序集的卸载问题

C# AppDomain 无法加载 DLL