使用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();

 

posted @ 2019-03-18 12:28  狂乱贵公子  阅读(1018)  评论(0编辑  收藏  举报