cad提供的 IExtensionApplication 接口 是不能实现一次以上的,那么这给编写代码带来了一种不好的情况是,每次都要去修改实现这个接口的类,
如果是一个小的测试功能,你又要去动前面的核心,这样就感觉很蛋疼....编程思维上面叫做"开闭原则":对拓展进行开放,对修改进行关闭.
所以我是这么想的,在实现IExtensionApplication接口的 Initialize 和 Terminate 时候,
用反射来找到某个接口(仿IExtensionApplication接口的),然后搜下面接口的 Initialize 和 Terminate,然后运行这个它.
仿IExtensionApplication接口的接口.
public interface IAutoGo { //打开cad的时候会自动执行 void Initialize(); //关闭cad的时候会自动执行 void Terminate(); }
继承 IExtensionApplication 接口的函数,cad加载这个dll,就会运行它.
public partial class AutoJJBox : IExtensionApplication { //为了解决IExtensionApplication在一个dll内无法多次实现接口的关系 //所以在这里反射加载所有的IAutoGo,以达到能分开写"启动运行"函数的目的 //打开cad的时候会自动执行 public void Initialize() { RunIAutoGo("Initialize");//方法名字 } //关闭cad的时候会自动执行 public void Terminate() { RunIAutoGo("Terminate");//方法名字 } private static void RunIAutoGo(string MethodName) { // 通过反射获取所有继承了IAutoGo接口的类! // 然后反射实例化,运行它! foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type type in assembly.GetTypes()) { foreach (Type t in type.GetInterfaces())//获得它的接口集合 { if (t.Name == "IAutoGo")//找到接口的函数 { //再找里面的Initialize foreach (MemberInfo item in type.GetMembers())//获得它的成员(函数 方法)的信息集合 { if (item.Name == MethodName) { try { string className = item.ReflectedType.FullName; //类名 string namePace = Assembly.GetExecutingAssembly().ToString(); Type ty = Assembly.Load(namePace).GetType(className); MethodInfo method = ty.GetMethod(MethodName); if (method.IsStatic)//判断是否静态方法,不是就要实例化 method.Invoke(null, null); else { //调用实例化方法(非静态方法)需要创建类型的一个实例 object instanceObject = Activator.CreateInstance(ty); object returnValue1 = method.Invoke(instanceObject, null); //运行所有的 IAutoGo的Initialize!! } } catch (System.Exception E) { throw E; } break; } } } } } } } }
封存上面的,之后也不用动了....
任何需要实现启动运行的函数,都去实现 : IAutoGo
public class AutoGo : IAutoGo { public void Initialize() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;//命令栏交互 ed.WriteMessage("惊惊博客是 https://www.cnblogs.com/JJBox/ "); } public void Terminate() { } }