原文:
C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载
AppDomain 表示应用程序域,它是一个应用程序在其中执行的独立环境。每个应用程序只有一个主应用程序域,但是一个应用程序可以创建多个子应用程序域。
因此可以通过 AppDomain 创建新的应用程序域,在新创建的子应用程序域中加载执行程序集并且在执行完毕后释放程序集资源,来实现系统在运行状态下,程序集的动态加载或卸载,从而达到系统运行中程序集热更新的目的。
所谓应用程序域,.Net引入的一个概念,指的是一种边界,它标识了代码的运行范围,在其中产生的任何行为,包括异常都不会影响到其他应用程序域,起到安全隔离的效果。也可以看成是一个轻量级的进程。
一个进程可以包含多个应用程序域,各个域之间相互独立。如下是一个.net进程的组成(图片来自网络)
以下为整个原理的实现代码
主应用程序入口:
using Kernel.ServiceAgent; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Remoting; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Kernel.App { class Program { static void Main(string[] args) { Console.WriteLine(""); using (ServiceManager<IObjcet> manager = new ServiceManager<IObjcet>()) { string result = manager.Proxy.Put("apprun one"); Console.WriteLine(result); Console.WriteLine(""); Console.WriteLine(" Thread AppDomain info "); Console.WriteLine(manager.CotrProxy.FriendlyName); Console.WriteLine(Thread.GetDomain().FriendlyName); Console.WriteLine(manager.CotrProxy.BaseDirectory); Console.WriteLine(manager.CotrProxy.ShadowCopyFiles); Console.WriteLine(""); } Console.ReadLine(); } } }
创建新的应用程序域并且在新的应用程序域中调用透明代理类:
using Kernel.Interface; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Security.Policy; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Kernel.ServiceAgent { public class ServiceManager<T> : IDisposable where T : class { private AppDomain ctorProxy = null; /// <summary> /// 应用程序运行域容器 /// </summary> public AppDomain CotrProxy { get { return ctorProxy; } } private T proxy = default(T); public T Proxy { get { if (proxy == null) { proxy = (T)InitProxy(AssemblyPlugs); } return proxy; } } private string assemblyPlugs; /// <summary> /// 外挂插件程序集目录路径 /// </summary> public string AssemblyPlugs { get { assemblyPlugs = ConfigHelper.GetVaule("