• 使用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();
  • 相关阅读:
    LVS 模式
    修改RocketMQ的NameServer端口
    一次清理Hbase的oldWALs的过程
    Linux下删除文件系统空间不释放的问题
    HBase 强制删除表
    关闭Found duplicated code
    Java操作HDFS代码样例
    RocketMQ:Cannot allocate memory
    Storm的StreamID使用样例(版本1.0.2)
    android studio 编译sdk版降低报错解决方法
  • 原文地址:https://www.cnblogs.com/saving/p/10551441.html
Copyright © 2020-2023  润新知