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. 在 VSCode 调试过程中,使用 Watcher,免手动重新编译

    1.安装Microsoft.DotNet.Watcher.Tools包 dotnet add package Microsoft.DotNet.Watcher.Tools --version 2.0. ...

  2. dapperDemo

    dapperDemo 下载链接:http://pan.baidu.com/s/1geQHXPT

  3. Gin-Go学习笔记二:Gin-Web框架

    Gin-Web框架 1>     首先声明,这个是我自己搭建的纯Gin-Web框架,其中有借鉴学习别的想法和代码.已上传到GitHub上.地址为: https://github.com/weiy ...

  4. windows 提权脚本利用

    本地加载: Import-Module Sherlock.ps1 远程加载: IEX (New-Object System.Net.Webclient).DownloadString('https:/ ...

  5. Web API接口安全了解

    2017版OWASP top 10 将API安全纳入其中,足以说明API被广泛使用且安全问题严重.自己尝试整理一下,但限于本人搬砖经验还不足.水平有限,本文只能算是抛砖引玉,希望大伙不吝赐教. 了解W ...

  6. 简单几招提速 Kotlin Kapt编译

    https://droidyue.com/blog/2019/08/18/faster-kapt/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_ ...

  7. SQLServer2017自动备份数据库

    本文截图来源: 地址一:https://blog.csdn.net/u010944388/article/details/86674078 地址二:https://www.cnblogs.com/ja ...

  8. MySQL读写分离之MyCAT

    Mycat实现MySQL主从复制读写分离 MyCAT的安装及部署 1.部署jdk环境 MyCAT用Java开发,需要有JAVA运行环境,mycat依赖jdk1.7的环境 1)上传jdk [root@l ...

  9. Linux服务之DNS介绍

    DNS-------Domain Name System域名系统 介绍:DNS就是把域名和IP地址联系在一起的服务,有了DNS服务器,你就不用输入IP地址来访问一个网站,可以通过输入网址访问.     ...

  10. vs2017无法查看类图

    问题描述: 在解决方案右键项目,没有查看->查看类图选项 问题根据: VS安装时没有安装VS扩展中的类设计器 解决方案: 运行安装包,找到Other Tols勾选Visual Studio ex ...