C#单个程序集代码热更新

本文介绍了一种在单个应用程序域中实现C#代码热更新的方法,通过创建假的程序集来代理真实程序集的更新。在类A被类B调用时,假A监测真A的变动并动态加载最新代码,以此实现在不重启软件的情况下更新部分代码。这种方法涉及到对象引用、类型信息存储以及反射调用等技术。
摘要由CSDN通过智能技术生成

 有的时候我们想更新我们正在执行中的代码,而不想软件重启。

  微软提供的标准方法是通过应用程序域来实现代码热更新,意思就是说,把自己想要进行热更新的代码放到另外一个应用程序域中,在检测到代码需要变更的时候,卸载掉那个程序域然后重新加载来实现代码热更新。按照微软的说法,一个应用程序域是无法实现代码热更新的。

  但是,一下方法确实是可以在单个应用程序域中实现代码热更新的,本人尝试过,在公司的上班中,软件的频繁重启让人很烦,又不能在另外一个程序域中执行,所以尝试了一下办法,在一个应用程序域中改变代码是可行的。

  方法如下:假设程序集A中有类a,程序集B中有类b,b要去调用a的方法,这个情况下可以对a的部分代码(仅对方法和属性有效)进行热更新。第一步是针对类a 进行代码重写,生成一个假的A.dll,但是具有和包含真A中类,字段,属性,和方法签名,把真A的Dll放到另外一个文件夹。当B去调用A中方法的时候,假的A会通过字节数组的形式将真A保存在自己的一个Assembly(最好放在一个其他类的静态变量中,我是那么做的)变量中,并且检测真A的文件改动,当真A发生变化的时候对Assembly变量通过字节数组的形式重新赋值。这个样子就可以就可以实现部分代码热更新。

  假A对真A代码的重写原则:假a类中至少要有三个变量,一个object变量,用来存对真a对象的引用。一个Type变量,用来存储真a的类型信息,还有真A的Assembly变量。假a在初始化的时候,要初始化刚才的那三个变量,对假a方法的调用通过反射转换为对真a对象(object变量,用来存对真a对象的引用)的调用。并且把真a方法的返回结果返回回去在真A变化之后,假A重新加载真A,这个时间点之后,在被创建的假a执行的代码已经是代码变化之后真A的代码,就可以实现代码特更新。

  把真A代码重构并且生成编译出假A是一个很费劲容易出错的过程,如下是我生成假A的代码逻辑,应该是存在某些问题的(嘿嘿,主要是说明方法)

using Microsoft.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DllLoad
{
    class Core2
    {


        List<string> dlls = new List<string>();
        string outpath = string.Empty;

        public EventHandler CompileCompleted;

        public Core2()
        {
        }

        public void SetInfo(List<string> dlls, string outpath)
        {
            this.dlls = dlls;
            this.outpath = outpath;
        }


        public void StartCompile()
        {
            try
            {
                dlls.ForEach(o =>
                {
                    Assembly assem = Assembly.LoadFrom(o);
                    Compile(assem, outpath);
                });
            }
            catch (Exception e)
            {
                KeyValuePair<bool, string> error = new KeyValuePair<bool, string>(false, e.Message);
                CompileCompleted(error, null);
                return;
            }
            KeyValuePair<bool, strin
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值