Skip to content

热重载

在程序的运行过程中,出现已知BUG,需要修改部分逻辑,但发布新版本会有较大的风险或需要较长的时间,此时就可以使用热重载。热重载是指在不停止程序运行的情况下,替换现有逻辑。
通常意义的热重载是在开发环境用于调试程序时,IDE所提供的功能。而AsDI所提供的热重载主要用于生产环境。
热重载通过监控指定目录及其子目录下的 dll 文件达到更新实现逻辑的目的,默认目录是程序所在目录。也就是说,当dll文件被写入到指定目录时,热重载会自动加载它,并更新相关业务逻辑,

开启热重载

在程序开始时(通常是Main函数中),首先开启热重载

C#
[Include]
public class Program
{
    static void Main(string[] args)
    {
        HotReload.Start();  //开启热重载(需要在最前面执行)
        AsDIContext.Start();
        //...
    }
}

也可以指定路径

C#
[Include]
public class Program
{
    static void Main(string[] args)
    {
        HotReload.Start(@"C:\HotReload\");  //指定路径,dll复制进此文件夹后生效
        AsDIContext.Start();
        //...
    }
}

基本示例

例如,一个解决方案下项目结构如下图: 项目结构

  1. AsDI.Template.App 应用程序,引用了AsDI.Template.IServicesAsDI.Template.Services
  2. AsDI.Template.IServices 服务接口,定义所有服务
  3. AsDI.Template.Services 服务实现,引用了AsDI.Template.IServices

在AsDI.Template.IServices中定义了一个ITestService服务,如下:

C#
namespace AsDI.Template.IServices
{
    public interface ITestService
    {
        /// <summary>
        /// 获取服务名称
        /// </summary>
        /// <returns>服务名称</returns>
        string GetServiceName();

    }
}

在AsDI.Template.Services中实现了ITestService服务,如下:

C#
namespace AsDI.Template.Services
{
    [Service]
    public class TestService : ITestService
    {
        public string GetServiceName()
        {
            return "Normal Business Logic";
        }
    }
}

此时,在AsDI.Template.App应用中调用了此服务。为了方便后续的加入HotReload介入,定义一个循环去不断输出服务获取到的内容,如下:

C#
namespace AsDI.Template.App
{
    [Include]
    public class Program
    {

        [AutoAssemble]
        private static ITestService service;

        static void Main(string[] args)
        {
            AsDIContext.Start();
            while (true)
            {
                Console.WriteLine(service.GetServiceName());
                Thread.Sleep(5000);
            }
        }
    }
}

运行程序后,输出如下:

sh
> Normal Business Logic
> Normal Business Logic
> Normal Business Logic
> Normal Business Logic
> Normal Business Logic
> Normal Business Logic
...

在程序的运行过程中,发现程序有问题 ,我们可以立即建立一个新的项目(或者长期包括此项目)AsDI.Template.HotReload,此项目引用了AsDI.Template.IServices,并实现ITestService服务,如下:

C#
namespace AsDI.Template.HotReload
{
    [Service(1)]
    public class TestHotReloadService : ITestService
    {
        public string GetServiceName()
        {
            return "HotReload Business Logic";
        }
    }
}

此时,我们只需要将AsDI.Template.HotReload项目生成的AsDI.Template.HotReload.dll文件,复制到发布后的HotReload指定的文件夹中,就会立即生效。生效后输出的效果如下:

sh
...
> Normal Business Logic
> Normal Business Logic
> Normal Business Logic            /** 复制前 */
> HotReload Business Logic         /** 复制后 */
> HotReload Business Logic
> HotReload Business Logic
...

如果发现HotReload问题更大,需要立即撤回,可以立即删除对应的AsDI.Template.HotReload.dll文件,程序会立即恢复到原来的逻辑,输出效果如下:

sh
...
> Normal Business Logic
> Normal Business Logic           /** 复制前 */
> HotReload Business Logic        /** 复制后 */
> HotReload Business Logic
> HotReload Business Logic
> HotReload Business Logic
> HotReload Business Logic
> HotReload Business Logic
> HotReload Business Logic        /** 删除前 */
> Normal Business Logic           /** 删除后 */
> Normal Business Logic
...

注意

  1. 热重载只能更新通过接口或抽象类的方式注入的服务
  2. 热重载的服务版本一定要高于原有的版本,否则不会替换

沪ICP备2025119739号