# 开发历史和特色

# 年代

# vc4.0 时代

还是vc4.0 时代, 本人被“国家分配”至某省电子研究所,担任“软件工程师”,有幸加入某“铁道用制票检票机项目”,开始了程序狗的生涯。当时为了配合硬件工程师调试样机,需要用C写大量的测试用例(界面)调用inport()、outport()来做测试。刚开始任劳任怨第每天复制/粘贴代码,后来一想不对,不能这样浪费青春,于是决定偷懒,按不同测试类型用不同的.ini文件做了一个界面生成器,有新的测试,只需要复制一下.ini文件,改一下参数就行了。最后这个任务就转给硬件工程师自己做了。这算是这个框架的萌芽吧。

# .net 2.0 时代

后来在.net Framework 2.0时代,在某电子公司任职时,恰逢公司引进当时全球领先的一种“视觉检测设备”。但是公司的需求与设备有一些不一致的地方(签合同时并没有搞清楚),要求供应商修改主程序(其实就是界面和某些运行参数),被告知一个天价;于是从某国公司总部请来了软件工程师和硬件工程师决定对该设备进行改造。在与软件工程师进行本专业的友好交流时,被强行拉入这个“视觉检测设备”的引进和改造项目。供应商也许出于内疚,破天荒提供了基于OPC协议的COM接口程序, 于是总部软件工程师负责接口程序的编写,本人负责界面程序---通过配置文件实现系列测试界面进行设备调试和校勘;最后做了一个外挂的界面实现非常规的项目检测;这算是这个框架的出生元年吧。

# .net4.0 时代

转眼到了.net Framework 4.0时代,本人在某包装公司任职,集团总部决策层崇欧尚美,一直走在实践国际化企业管理理论的前列。躬逢其盛,在本人入职的第二年,公司同时落地ISMS和ITIL项目。政策和流程文件多达几百页,但是,所有流程在服务器和用户端电脑上的操作如监控/巡检/配置/部署等是需要手工或半手工(写点脚本)进行的,而且其中2个异地工厂(也有几台服务器和几十台用户端电脑)是没有专职IT人员的,分别由一位财务大姐和一位电工兄弟兼职!!多次提议上一个HP/DELL/MS的运维自动化系统,管理层推三阻四。眼看运维组的兄弟要一个个辞职了,他们的乱事就要落到我头上,还有重新招人培训等烦心事,这叫我如何安静写代码? 某天晚上突然醍醐灌顶,意识到所有的这些手工或半手工的操作不就是对运维对象--诸如文件、注册表、主策略、用户及用户组的处理还有软件安装/卸载、网络/数据库/电脑性能检测监控的操作吗?这些都可以程序实现,繁琐的事只不过是要移步到每台电脑,做大量的手指重复的敲键盘的动作而已。何不利用以前的程序框架做一个运维自动化系统,让运维兄弟们足不出户,通过预先设置、一次敲鼠标,批量完成这些重复动作,甚至可以从“一键完成”到通过Windows服务进行无人值守的调度部署,通过Socket/Mqtt等远程通讯协议编程实时远程实时部署?说干就干,当天凌晨画了需求框架,然后封闭开发一周,一周后初步完成就拿去救火,这算是这个框架的1.0版本吧。
后来再把这套框架拿来做了公司的Intranet应用、HR系统,算是这个框架的2.0版本。
后来有一个软件公司做开发总监的朋友,看到这个东西后,觉得特别适合他们做软件测试,于是就拿给他们试用。他们居然把这套东西用出“花”来了(UI测试、压力测试、功能测试、数据Mock),在界面的重用性方面提出了很多具体的需求。他们需要在功能测试、数据Mock方面只配置一套界面,然后通过xml或json文件来动态产生不同的界面,参考他们的反馈和建议,反复迭代、修改----抽象、解耦、提纯,就演变成了今天的共享给大家的这个东西。算是这个框架的3.0版本。

# .net Core 时代

再后来,在.Net Core时代,本人已经沦落为一个专职的“码农”了, 用这套架构做了CMS、ERP、MES等项目, 进一步理解了“软件设计之美”、“软件架构之美”的内涵。写代码的时候觉得别扭的地方,一定是设计没抓到要害,模型还不够纯粹。就像看一块石头和看一块水晶,当你觉得你的模型看起来像一块石头,摸起来硌手的时候,那一定是设计还有改进的空间,当你逐渐提纯之后,就有看一块水晶的感觉了。例如本框架的Resize,一直是跟着Menu走,写代码/配置界面的时候,总是觉得“硌手”,后来某一天突然醒悟,它应该跟着View(作为Web客户端是Route->View)才是真理,这么一改,后续的代码和配置就有了一种通透的感觉。 在疫情期间,有了一点时间,把在几个项目中的改进做了一个大的整合,终于有了一点看水晶的感觉了,作为这个框架的3.5.2版本。

# .net 6 时代

也就是今年,刚好空闲下来,从六一儿童节到圣诞节,花了差不多半年时间的对3.5.2版本进行去毛刺、打磨---增加校验点、字段验证功能的简化、重用性方面增加控件组的概念、配置文件从仅支持.xml到全面支持excel/csv/xml/json、以IOC代替反射等,增加了外置Shell、外置UI、外置标准服务、中心交换数据、Action/Service Watcher等功能;作为这个框架的3.5.3版本。感觉重构的空间已经不大了,该版本应该可以成为一个长期稳定版本吧。
另外我会把上面提到的运维自动化工具系统匹配到最新版本的框架,写成另外一个专题“Windows运维自动化编程实战”,演示如何通过无码化编程方式集成进本框架,也会陆续分享给大家。

# 一些感悟

本人20多年职业生涯, 除了刚开始的2年和最近这几年的专职开发经历,大部分的时间是在制造业从事实施应用等工作,每天面对的是各种奇葩用户和企业自身的各种个性化的非标的业务需求;也实施运维过从基础设施软件如安全/协作类系统到CAD、SCM/ERP/MES、PLM、CRM等各种优秀的管理信息系统,在“用”这些系统的同时, 总喜欢“不务正业”地琢磨它们的业务和技术架构,是不是我也可以照虎画猫做一套类似的系统,或者可以做的更好,让最奇葩的用户也可以毫无障碍地使用?同时满足各种非标的业务需求?当然这些异想天开的想法没有实现,但是在脑子里也留下了一些痕迹。比如PTC/SDRC的CAD软件的(变)参数化设计的思想,既然机械工程师可以参数化地画出一套机械系统,那么非软件工程师是不是也可以参数化地“画”出一套软件系统?还有SAP GUI的Tcode、界面Profile、权限管理,Symantec SEP的安全策略和华丽简洁的界面,SAP ERP的配置化以及SalesForce CRM的定制化;这些痕迹都或多或少渗透到了这套框架里。
特别是SAP ERP,跟它打交道十多年,也琢磨了十多年,总的感悟,它的配置化实现的架构基于: 技术实现对业务的向上的高度抽象/提纯/封装,向下的独立性实现---分层/分类/模块化/组件化--的结合,从而实现多态性,实现可复用的弱耦合、后绑定软件架构。

# 本框架的特色

# 配置化-化繁为简

界面(UI)、过程控制(Shell)、基础功能通过配置实现,把程序员从繁琐重复的劳动中解放出来,提高开发效率,缩短开发周期。适用于所有.net开发人员和组织。
EasyWinForm完全可以高仿 SAP GUI、SEP客户端、360安全卫士客户端的界面,并且是完全通过配置文件实现。.net的Winform的拖拉控件上手很快,但是要实现一些复杂的功能还是需要一些经验和奇巧淫技的,比如实现界面统一风格和样式、以单窗体模仿多窗体效果、点关闭按钮只是最小化、弹出一个非Modal的对话框、隐藏/显示(切换)一侧的区域等等。即使对于一个Winform的熟手,在修改或拷贝一个多层继承带有Resource的的Form时,一不小心就会弄出各种莫名其妙的错误---如多出一个Design1.cs文件、修改被继承的Form属性,继承Form就报错或排序、位置等没有变化,这个对Winform的开发人员来说应该是深有体会的。如果使用EasyWinform,所有的界面元素完全是通过配置文件实现,完全不会出现以上情况,这个工作交给一个IT文员来做是完全可以胜任的。
核心工程师只需要把精力放到实现核心业务逻辑的代码,通过“外嵌”组件的方式交付给IT文员或用户, IT文员再通过Shell配置实现UI可视化、过程控制和流程自动化,核心工程师只需要集中精力写“核心”业务代码,这些业务逻辑的代码可以写的非常简洁(函数式)。

# 参数化、内置和外嵌-实现多态性

框架内内置(built-in)了密码验证、权限管理、基础UI库、过程控制和基础功能(字符、文件处理, 逻辑、数值运算, 数据输入输出、数据格式转换、加密解密、输入验证、表单字段验证等...),完成通用的业务实现;通过启动程序参数、公式参数、Shell参数、标准服务参数实现传参;可以外嵌(outer-embeded)的组件包括:外嵌UI库、 外嵌核心业务处理(CBLP)组件、外嵌标准服务(OeStdService)组件、外嵌Shell(实现RPA);这些外嵌的组件通过IOC实现调用(外嵌Shell可以配置实现),实现“即插即用”;可以使用这些组件以搭积木的方式按需“丰俭由人”、“即兴”组合成各种应用,如C/S程序客户端、Web客户端、上位机开发调试 、办公应用 、自动化测试、数据处理分析等。
当然所有配置文件的内容也可以放在数据库,通过公式的方式获取。
不管系统架构是怎样的(连接嵌入式设备、直连数据库或服务端+客户端形式),前端界面和过程控制完全靠配置实现,后端动态加载外置组件, 前端传参驱动后端功能,前后端就完全实现了解耦,从而实现多态性,后绑定,实现可复用的效果。
比如一个ERP系统,MRP运算、复式记账法这种公式定理一样的东西,把它写在CBLP组件里,做到千年不变;变的只是流程、场景、可视化的一些东西,可以把它们放到前端、通过传参+配置差异化地实现功能。
再比如我们即将介绍的运维自动化系统,把对运维对象的操作写在外嵌标准服务(OeStdService)组件里,变的部分如:按密码管理策略每周修改密码、注册表里WSUS服务器地址要紧急改动、明天ISMS政策又增加了对屏保的管理、由于专线中断临时修改所有电脑的host文件、需要临时清查盗版软件等等,这些在里在UI配置增加一个表单,或在Shell配置里增加/修改一个Procedure就可以搞定了;对于这些变更,根本不需程序员出手。
总而言之:内置的东西千年不变、CBLP以不变应万变;传参+配置的组合是以万变应不变。对需求多变、需求不明确、需求选项多的场景特别适用,例如软件测试、嵌入式设备开发调试、需求阶段的原型设计、以及运维管理等应用。

# 支持各种运行模式

本框架支持各种运行模式(同步、异步、异步等待、可管理的线程),只需在UI配置文件的Action和Shell配置文件的Transaction的ExecMode选项里填写Sync/Asyn/AsynAwaited/ManagedThead即可实现。“异步”用来实现与主体流程并发的事务;“异步等待”用来实现与主体流程不能并发的异步事务、防止Form虚化;
“可管理的线程”实现与主体流程并发的事务,按线程池最大线程数量动态加载,可以取消、暂停,用来实现耗时操作-如下载、爬虫、数据采集等,结合Shell实现无人值守的定制化操作,也可用来实现连续进行、但需要人工干预中断的事务,如录音机、试验设备的控制等。

# 多语言支持

实现多语言支持只需在ApplicationSetting配置里做一个参数设置,然后在UI配置文件夹里加一个多语言文本对照的配置文件即可实现。
本框架的多语言支持的特点是: Culture对language是一对多的关系而不是Culture和Languge绑定;这也是多年外企的系统实施运维工作中Get到的一个点;比方说外国工作人员来中国工作,他用系统时,语言选择是英语,用到的是本地化时间(比如考勤、订机票)和货币(报销);通用的zh-CN/en-US这种Culture和Languge绑定的形式就不能贴切地满足需求。


所以本框架也适合跨国公司作为管理系统开发框架使用。

# 在此基础之上,实现无码化编程。