C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载

本文介绍了如何利用C#的AppDomain特性创建子应用程序域,以实现在运行状态下动态加载或卸载程序集,达到程序集热更新的目的。通过创建透明代理类,并在代理类中操作资源,可以实现跨域的安全隔离和资源管理。文章还给出了具体的代码示例,详细阐述了加载、执行和释放程序集的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文: 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("
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值