C#如何实现从内存中加载程序集
首先,为了动态的在内存中装载程序或程序集,我们以文件流的方式读取二进制文件,并将其以字节的形式保存在数组中,代码如下: //动态加载插件 String pluginFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\plugins\\PluginLibrary.dll"; FileStream fs = new FileStream(pluginFilePath, FileMode.Open); BinaryReader br = new BinaryReader(fs); byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length)); fs.Close(); br.Close();
然后,利用 Assembly 类的 Load 重载方法,以数组的形式加载该程序集。代码如下: 动态加载DLL(C#) public class PlugingManager { //插件装载器 public ArrayList Plugins = new ArrayList(); //插件FullName public ArrayList PlugFullName = new ArrayList(); //插件类型 public ArrayList PlugTypes = new ArrayList(); #region 构造函数 /// <summary> /// PlugingManager插件加载 /// </summary> /// <param name="plugspath">插件所在目录必须是运行目录中的文件夹</param> /// <param name="StartsWith">加载指定插件(插件包含的名称)</param> /// <param name="InterfaceName">插件接口名称</param> public PlugingManager(string plugspath,string StartsWith,string InterfaceName) { //获取插件目录(plugins)下所有文件 string[] files = Directory.GetFiles(Application.StartupPath + @"\\" + plugspath); foreach (string file in files) { if (file.ToUpper().EndsWith(StartsWith.ToUpper())) { try { //Assembly ab = Assembly.LoadFrom(file); Assembly ab = null; //先将插件拷贝到内存缓冲 byte[] addinStream = null; using(FileStream input = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader reader = new BinaryReader(input); addinStream = reader.ReadBytes((int) input.Length); } ab = Assembly.Load(addinStream); //加载内存中的Dll Type[] types = ab.GetTypes(); foreach (Type t in types) { if (t.GetInterface(InterfaceName) != null) { Plugins.Add(ab.CreateInstance(t.FullName)); PlugFullName.Add(t.FullName); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } } #endregion } new PlugingManager("Plugs", "Garden.Plugs.dll", "IPlug"); PlugingManager plug = var win = plug.Plugins.ToArray().FirstOrDefault(m => ((Type)m.GetType()).Name.ToLower() == this.Tag.ToString().ToLower()); MethodInfo OnShowDlg = ((Type)win.GetType()).GetMethod("ShowSelf"); Form cl = (Form)OnShowDlg.Invoke(win, null); cl.WindowState = FormWindowState.Maximized; cl.MdiParent = this; cl.Show(); foreach (object obj in plug.Plugins) { Type t = obj.GetType(); MethodInfo OnShowDlg = t.GetMethod("ShowSelf"); Control cl = (Control)OnShowDlg.Invoke(obj, null); Control con = GetControlFromForm(t.Name, this); if (con != null) { con.Controls.Add(cl); cl.Dock = DockStyle.Fill; isbreak = false; con = null; } } |
|