1.  Assembly中的类要从MarshalByRefObject继承,如果你想从你自己的类来继承,那么请选用interface或者继续研究其他解决方案。

namespace Library
{
public class MyClass : MarshalByRefObject
{
}
}

其中MyClass的方法的返回值和参数必须是简单类型或者可序列化的。
2. 调用程序中,实现一个加载Assembly的辅助类,比如叫做LoadHelper,它也从MarshalByRefObject继承。在这个类里对Type的方法作一些封装,完成对MyClass中的方法的调用。如:

//name:方法名
public object InvokeMethod(string name, object obj, object[] paras)
{
return obj.GetType().InvokeMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, obj, paras);
}

Type的其他方法也可以在此进行封装。总而言之,把需要进行反射的代码都写在这里。封装的形式可以有多种方式,上面这个方法是在外部创建了一个对象实例,调用时传递给这个方法,再通过反射调用其方法。其实这种方式是效率比较低的,因为那个obj要在两个AppDomain之间传递,而跨AppDomain传递对象是要将这个对象序列化和反序列化的。所以为了改善效率,可以在这里临时创建对象。
比如:

public object InvokeInstanceMethodNotCachedAsm(string name, string assemblyFile, string typeName, object[] paras)
{
object obj;
Assembly asm = Load(assemblyFile);
obj = asm.CreateInstance(typeName);
return obj.GetType().InvokeMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, obj, paras);
}

甚至还可以采取将Assembly缓存的机制,这样调用起来速度更快。
3.调用程序中加载和卸载AppDomain:

static void Load()
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
setup.ShadowCopyFiles = "true";
setup.ShadowCopyDirectories = "需要动态加载的Assembly所在文件夹";//影像副本目录
setup.ApplicationName = "Dynamic";
// Set up the Evidence
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
Evidence evidence = new Evidence(baseEvidence);
// Create the AppDomain
appDomain = AppDomain.CreateDomain("newDomain", evidence, setup);
loader = (LoadHelper)appDomain.CreateInstanceAndUnwrap("程序的AssemblyName", "那个辅助类的全名");
}
static void Unload()
{
AppDomain.Unload(appDomain);
}

在这里,有三点是关键,一是创建一个新的AppDomain,二是让这个新的AppDomain允许使用影像副本文件,三是要把影像副本目录设为非主程序所在文件夹。
这是因为.Net不允许卸载一个已加载的Assembly,除非卸载整个AppDomain,允许使用影像副本,.Net就把要加载的Assembly复制到另一个文件夹(在用户配置文件夹中),但程序所在文件夹中的Assembly并不被复制。

4.创建对象实例
object  obj = appDomain.CreateInstanceFromAndUnwrap("Assembly文件名含路径",  "类名");
这样就创建了一个指定的类的实例,但是,不要试图对这个obj进行反射,对这个obj进行反射,不能得到其实际类型的信息,因为在主程序文件夹中没有部署那个Assembly,而只会得到其已部署的基类和接口类型,只能对这些类型进行操作。
5. 调用
如果在主程序的AppDomain中加载了所创建的对象的基类或者接口类型,那么可以调用这些类型的相关成员。
如果没有,那么就通过调用LoadHelper中的相关方法来调用。
6.卸载与替换
程序运行起来后,Assembly所在文件夹中的这个已加载的Assembly文件,是可以被删除的,因为实际上加载的那个文件是其副本,删除之后程序照样运行,而替换一个新的,也不会起作用。只有当调用上面的Unload和Load方法,卸载和重新加载后,新的Assembly才会起作用.

C#动态加载/卸载Assembly的解决方案的更多相关文章

  1. c#动态加载卸载DLL的方法

    这篇文章介绍了c#动态加载卸载DLL的方法,有需要的朋友可以参考一下 c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法.在 ...

  2. 2018-2-13-C#-动态加载卸载-DLL

    title author date CreateTime categories C# 动态加载卸载 DLL lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:2 ...

  3. C# 动态加载卸载 DLL

    我最近做的软件,需要检测dll或exe是否混淆,需要反射获得类名,这时发现,C#可以加载DLL,但不能卸载DLL.于是在网上找到一个方法,可以动态加载DLL,不使用时可以卸载. 我在写一个WPF 程序 ...

  4. c#动态加载卸载DLL

    前段时间工作的时候遇到一个问题.就是需要每次启动程序的时候动态替换掉某个dll,所以就百度了这方面的资料.这次记录下来让自己以后可以看. 根据自己的理解,动态卸载dll需要有以下条件: 1:dll在加 ...

  5. js插件动态加载js、css解决方案

    最近因为工作需要做了一个js自动导入的插件,一开始很天真的以为动态创建个script添加到head中就ok了,试了之后才发现了问题,就是如果同时引入了多个js文件,而且后一个文件中用到了前一个文件中的 ...

  6. CE驱动动态加载卸载

    加载: #define DEV_KEY TEXT("Drivers\\Builtin\\WCDMA") BOOL CGPRSCTRLDlg::Load() { //DWORD dw ...

  7. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

    实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...

  8. 反射 type 的基本用法,动态加载插件

    这里介绍反射的简单实用 MyClass类 public class MyClass { public int Age { get; set; } public string Name { get; s ...

  9. goloader - golang动态加载的实现

    github地址:https://github.com/dearplain/goloader 这里有以前的一些思路:http://www.cnblogs.com/dearplain/p/8145985 ...

随机推荐

  1. angular基于ui-router实现系统权限控制

    前端去实现权限控制听起来有点扯淡(实际也有点扯淡),掩耳盗铃,主要是担心安全问题,但是如果在前后端分离的情况下,需要做一个带有权限控制的后台管理系统,angular基于ui-router应该怎么做呢? ...

  2. 高斯消元与期望DP

    高斯消元可以解决一系列DP序混乱的无向图上(期望)DP DP序 DP序是一道DP的所有状态的一个排列,使状态x所需的所有前置状态都位于状态x前: (通俗的说,在一个状态转移方程中‘=’左侧的状态应该在 ...

  3. 慕课网 jQuery 笔记

    $("div").html()是使用标签选择器获取div标签,对应于javascript中的各类选择器 $("*") ——所有元素 $("#lastn ...

  4. string.replace替换

    var str = 'abcadeacf'; var str1 = str.replace('a', 'o'); alert(str1); // 打印结果: obcadeacf var str2 = ...

  5. CSS之浮动布局(float,浮动原理,清除/闭合浮动方法)

    css之浮动布局 本人博客:查看文章   1.什么是浮动:在我们布局的时用到的一种技术,能够方便我们进行布局,通过让元素浮动,我们可以使元素在水平上左右移动,再通过margin属性调整位置 2.浮动的 ...

  6. AngularJs 第一个自定义指令编写

    公司在做一个OA系统, 包括移动端(从微信企业号进入OA系统),电脑端. 电脑端还是用的传统的easyui做界面,asp.net mvc作为服务端.这个技术已经很成熟了配合权限框架很快就能开发出来.但 ...

  7. demo.testfire.net 靶场测试流程记录

    demo.testfire.net span::selection, .CodeMirror-line > span > span::selection { background: #d7 ...

  8. DOMINO的JDBC和ODBC连接方法

     利用ODBC实现Domino和关系数据库的互操作 Lotus Domino是当今办公自动化系统的主流开发平台之一,Domino自带一个非关系型数据库–文档型数据库,而目前大部分企业的信息都储存在 ...

  9. Selenium clear()方法无法清掉数据

    问题描述 clear()方法执行过后, 数据还是在. 根本原因 存在镜像节点. 操作clear()清掉数据后, 镜像节点的数据还在, 就会再补充回去. 解决办法 添加下面代码就可以连同镜像的数据一起去 ...

  10. java笔记--守护线程的应用

    守护线程的应用 Java中的线程可以分为两类,即用户线程和守护线程.用户线程是为了完成任务,而守护线程是为其他线程服务 --如果朋友您想转载本文章请注明转载地址"http://www.cnb ...