.NET实现热插拔功能(动态替换功用)方案实例

  几种方案

  1 脚本化:采用 Iron 或 集成其它脚本引擎。

  2 AppDomain:微软的 Add In 框架就是为这个目的设计的。

  3 分布式 + 负载平衡 :轮流更新集群中的服务器。

  4 Assembly.LoadFrom + 强签名程序集:因为相同标识的程序集在内存中只会加载一次,所以每次功能发生变化,都要增加程序集的版本号。

  5 Assembly.Load +  + 强签名程序集 + GAC:因为相同标识的程序集在内存中只会加载一次,所以每次功能发生变化,都要增加程序集的版本号。

  6 Assembly.LoadFile:Assembly.LoadFile 可以多次加载相同标识的程序集,只要程序集所在的目录位置不同。

  重点说一下 Assembly.LoadFile

.NET实现热插拔功能(动态替换功用)方案实例

  测试代码

  

复制代码 代码如下:

  using System;

  using System.Collections.Generic;

  using System.Linq;

  using System.Text;

  using System.Threading.Tasks;

  using System.Reflection;

  using System.IO;

  using Contracts;

  namespace Test

  {

  class Program

  {

  static void Main(string[] args)

  {

  SetupPlugEnvironment();

  ExecuteOperator("1.0.0.0");

  ExecuteOperator("2.0.0.0");

  }

  private static void ExecuteOperator(string version)

  {

  var operatorType = Type.GetType("Implements.Operator, Implements, version = " + version + "");

  var operatorInstance = Activator.CreateInstance(operatorType) as IOperator;

  operatorInstance.Operate();

  }

  private static void SetupPlugEnvironment()

  {

  AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

  }

  static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)

  {

  AssemblyName name = new AssemblyName(args.Name);

  var file = Path.Combine(

  @"E:\Coding\HappyStudy\LoadContextStudy\Test\bin\Debug\Plugs",

  name.Name,

  name.Version.ToString(),

  name.Name + ".dll");

  Console.WriteLine("加载插件:" + name.Version);

  return Assembly.LoadFile(file);

  }

  }

  }

.NET实现热插拔功能(动态替换功用)方案实例

  

  说明

  调用 Type.GetType 会导致 CLR 执行程序集探测过程,在正常的探测路径下没有找到程序集就会触发 AssemblyResolve 事件,为啥会触发两次呢?我还不知道。

  微软不推荐使用 LoadFile(会加载相同标识的程序集多次),Add In 采用的是 AppDomain,MEF 采用的是 LoadFrom。