cad提供的 IExtensionApplication 接口 是不能实现一次以上的,那么这给编写代码带来了一种不好的情况是,每次都要去修改实现这个接口的类,

如果是一个小的测试功能,你又要去动前面的核心,这样就感觉很蛋疼....编程思维上面叫做"开闭原则":对拓展进行开放,对修改进行关闭.

所以我是这么想的,在实现IExtensionApplication接口的 Initialize 和  Terminate 时候,

用反射来找到某个接口(仿IExtensionApplication接口的),然后搜下面接口的 Initialize 和  Terminate,然后运行这个它.

20191227增加了控制加载顺序的函数

仿IExtensionApplication接口的接口.

    /// <summary>
/// 控制加载顺序
/// </summary>
public enum Sequence : byte
{
First,// 最先
Last, // 最后
} public interface IAutoGo
{
// 控制加载顺序
Sequence SequenceId(); // 关闭cad的时候会自动执行
void Terminate(); //打开cad的时候会自动执行
void Initialize();
}

继承 IExtensionApplication 接口的函数,cad加载这个dll,就会运行它.

    class RunClass
{
Type _ty;
public string NamePace { get; private set; }
public string ClassName { get; private set; }
public Sequence SequenceId
{
get
{
Sequence sequence = Sequence.Last;
try
{
string sequenceId = "SequenceId";
_ty = Assembly.Load(NamePace).GetType(ClassName); //加载命名空间下的class
MethodInfo method = _ty.GetMethod(sequenceId); //获取这个class的方法 //居然是静态获取返回的枚举值
object instanceObject = Activator.CreateInstance(_ty);
object returnValue1 = method.Invoke(instanceObject, null); //运行
sequence = (Sequence)returnValue1;
}
catch
{ }
return sequence;
}
} public RunClass(string namePace, string className)
{
NamePace = namePace;
ClassName = className;
} public void Run(string methodInfoName)
{
try
{
MethodInfo method = _ty.GetMethod(methodInfoName); //获取这个class的方法
if (method.IsStatic)//判断是否静态方法
{
method.Invoke(null, null);//静态调用
}
else //非静态,调用实例化方法
{
object instanceObject = Activator.CreateInstance(_ty);
object returnValue1 = method.Invoke(instanceObject, null); //运行
}
}
catch (System.Exception)
{
throw;
}
}
} //为了解决IExtensionApplication在一个dll内无法多次实现接口的关系
//所以在这里反射加载所有的IAutoGo,以达到能分开写"启动运行"函数的目的
public class AutoClass : IExtensionApplication
{
//打开cad的时候会自动执行
public void Initialize()
{
RunIAutoGo("Initialize");
} //关闭cad的时候会自动执行
public void Terminate()
{
//可以用
//MessageBox.Show("哇哇哇哇哇"); //不可以用,此时的cad界面都已经关闭了...涉及内存释放的问题
//Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; RunIAutoGo("Terminate");
} // 通过反射获取所有继承了IAutoGo接口的类!
// https://www.cnblogs.com/yelanggu/p/5196156.html
// 然后反射实例化,运行它!
// https://www.cnblogs.com/yanshanshuo/p/3905621.html void RunIAutoGo(string methodName = "Initialize")
{
const string iAutoGo = "IAutoGo";
var typeList = new List<RunClass>(); //储存
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())//当前的应用程序域,也就是acad或者gcad的域
{
foreach (Type getTypes in assembly.GetTypes())//获取类型集合
{
foreach (Type getInterfaces in getTypes.GetInterfaces())//获取接口集合
{
if (getInterfaces != null &&
!string.IsNullOrEmpty(getInterfaces.Name) &&
getInterfaces.Name == iAutoGo)//找到接口的函数
{
//再找里面的Initialize
foreach (MemberInfo member in getTypes.GetMembers())//获得它的成员(函数 方法)的信息集合
{
if (member != null && !string.IsNullOrEmpty(member.Name))
{
if (member.Name == methodName)
{
string namePace = Assembly.GetExecutingAssembly().ToString(); //命名空间
string className = member.ReflectedType.FullName; //类名
typeList.Add(new RunClass(namePace, className));
break;
}
}
}
}
}
}
} //按照 SequenceId 排序
typeList = typeList.OrderBy(runClass => runClass.SequenceId).ToList(); var sb = new StringBuilder();
int num = ;
foreach (var item in typeList)
{
try
{
item.Run(methodName);
}
catch (System.Exception e)
{
num++;
sb.Append("错误");
sb.Append(num.ToString());
sb.Append("\n\r");
sb.Append("探索接口RunIAutoGo出错,错误NamePace:\n\r");
sb.Append(item.NamePace);
sb.Append("\n\r错误ClassName:\n\r");
sb.Append(item.ClassName);
sb.Append("\n\r错误信息:\n\r");
sb.Append(e.Message);
sb.Append("\n\r\n\r");
}
}
if (sb.Length > )
{
MessageBox.Show(sb.ToString(), "惊惊连盒");
}
}
}

封存上面的,之后也不用动了....

任何需要实现启动运行的函数,都去实现  : IAutoGo

注意一下

    public class Test : IAutoGo
{
public Sequence SequenceId()
{
//最好只使用一次,用于初始化工具集的路径之类的优先项
return Sequence.First; //其余均使用last
//return Sequence.Last;
} public void Initialize()
{ Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;//命令栏交互
ed.WriteMessage("惊惊博客是 https://www.cnblogs.com/JJBox/ ");
} public void Terminate()
{ }
}

cad.net IExtensionApplication接口的妙用 分开写"启动运行"函数的更多相关文章

  1. flask 中使用蓝图将路由分开写在不同文件

    flask 若想将不同的路由写在不同的文件中(如将 user 对象的相关接口写在一个文件中,将 customer 对象的相关接口写在另一个文件中),可以使用蓝图来实现. 有关蓝图的定义:A Bluep ...

  2. background低版本安卓浏览器不支持复合属性,要分开写

    background:url("http://..../xxx.jpg") no-repeat center/cover; 这种复合形式在有些低端安卓浏览器中不支持,最好分开写: ...

  3. C#深度学习の接口传参(interface)-----接口的妙用

    一.接口可以干嘛 我们知道,接口的本质是一个约束规范,委托是方法纵向(形式上)的封装,接口是不同方法横向(广度)的封装 接口中不能有变量,但是可以有属性方法.常见的,我们可以用接口: 1.实现需求方的 ...

  4. 易宝支付Demo,生产中封装成简洁的代付接口,不用request如何获取项目运行时的真实路径

    最近项目在做融360引流,涉及到了易宝支付的代扣和代付.易宝官方给出的demo只能简单运行,而且都是通过form表单的形式提交,返回XML格式.同时接口代码都写在了JSP中看起来不友好.项目在生成中想 ...

  5. 记录python接口自动化测试--把测试结果写进excel文件(第九目)

    python中一般使用xlrd(excel read)来读取Excel文件,使用xlwt(excel write)来生成Excel文件(可以控制Excel中单元格的格式),需要注意的是,用xlrd读取 ...

  6. ItcastOA_设计BaseDao_设计DAO接口和实现类_写DAO实现类中的方法内容

    3. 基础功能 3.1. 设计BaseDao接口与BaseDaoImpl类 每个实体都应有一个对应的Dao,他封装了对这个实体的数据库操作.例 实体Dao接口实现类 ================= ...

  7. 快速开发框架(FDMS)新增1000个对外接口都不须要手写一行代码

    一个大型系统难免会跟其它系统有数据交换,这里就要提供数据接口给外部系统. 曾经在一家智能终端设备的公司上班.那段时间的主要工作就是写接口.接口须要与手机.手持设备.系统管理软件等进行数据交换.总结了一 ...

  8. require js 将config和入口函数分开写

    原文地址 https://github.com/jrburke/requirejs/issues/354 Area there any plans to standardize/recommend a ...

  9. 为什么C++中声明和定义要分开写

    现在开始写项目了,你会发现我们一般都要写一个cpp,对应的还得有一个h文件,那么为什么在C++中我们要这么做? .h就是声明,.cpp就是实现,而所谓分离式实现就是指"声明"和&q ...

随机推荐

  1. java--Date时间

    Date: 表示特定的瞬间,精确到毫秒,通过方法设定自己所表示的时间,可以表示任意的时间 System.currentTimeMillis() :返回的当前系统时间, 1970-1-1 至今的毫秒数 ...

  2. iOS相关

    1. fastlane a collection of tools that help you automate building and releasing iOS and Android apps ...

  3. Django框架(二)-- 基本配置:app注册、模板配置、静态文件配置、数据库连接配置post和get

    一.app 在Django中,APP可以用以下类比 大学 --------------------项目 计算机学院------------app01 土木学院 ------------ app02 1 ...

  4. Java枚举的用法和原理深入

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10843644.html 一:枚举的用法 1.定义和组织常量 在JDK1.5之前,我们定义常量都是:publi ...

  5. MySQL的select详细介绍

    MySQL 查询数据 MySQL 数据库使用SQL SELECT语句来查询数据. 你可以通过 mysql> 命令提示窗口中在数据库中查询数据 语法 以下为在MySQL数据库中查询数据通用的 SE ...

  6. 利用python制作在线视频播放器遇到的一些问题

    经过前期的调研,我准备使用PyQT+PyAV+PyAudio+pillow.期间也尝试过使用ffmpeg-python,但最后还是选择了av这个更底层,自由度更大的库来完成音视频的处理.   ==== ...

  7. js的函数三角恋

    原创,转载请标明来源https://www.cnblogs.com/sogeisetsu/ js的函数三角恋 1.什么是构造函数 是专门用于创建对象的 对象就是object **** 1.什么是函数? ...

  8. 洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)

    题目链接:https://www.luogu.org/problem/P2463 [题意] 求出N个串中都出现的相同子串的最长长度,相同子串的定义如题:所有元素加上一个数变成另一个,则这两个串相同,可 ...

  9. wordpress如何添加自增变量(第一篇文章显示摘要后面的只显示标题)

    有时我们在调用文章列表的时候需要在前面添加序号看起来比较整齐,如何实现呢?要想精确的控制每篇文章,我们先在循环前定义一个变量 $ashu_i=1 来计数,变量名随便,然后每循环一次,$ashu_i加1 ...

  10. 如何让ThinkPHP支持模糊搜索

    最近ytkah在做一个ThinkPHP的项目时发现了一个问题,搜索的功能只能检索出以*为开头的内容,不能检索出中间的词.例如:搜索包含6775的产品,搜索结果为空,而搜索000-6775 就有两个结果 ...