其实本人之前一直主攻Web前后端的开发,但是由于业务需要,今年开始被分到了公司的自动化项目组搬砖,主要负责上位机的开发。看着项目组中参差不齐的开发模式,也没有具体的便于开发人员使用的项目开发框架,遂产生了设计一种通用开发框架的想法,最终在第一次自动化项目的开发工作中孕育出了WMS(Wpf.MvvmLight.SelfHost)。
Github: https://github.com/ForeverRG/Wpf.MvvmLight.SelfHost.git
Wpf.MvvmLight.SelfHost(简称WMS)是一款基于MVVMLight+SelfHost的WPF自动化项目便捷开发框架。
1.系统环境
2.核心
3.日志
4.持久层
5.视图层
在开发过程中,项目里其实有很多代码都是重复的,为了提高各位Coder的工作效率,让各位更专注于业务逻辑的开发,于是提供了代码自动生成功能。
我在上述开始的步骤中有提到过,在项目运行后,根目录会自动生成了数据库文件,这里的自动生成其实就是CodeFirst模式。
<connectionStrings>
<add name="SQLiteConnStr" connectionString="URControl.db" />
connectionStrings>
public void InitDatabaseAndTables()
{
InitDB(false, 300,
typeof(ControlCenter),
typeof(PLC),
typeof(Robot),
typeof(TestBench),
typeof(VisionModel),
typeof(Jig),
typeof(ModuleSettings),
typeof(Tray),
typeof(Config),
typeof(Channel),
typeof(ModuleType),
typeof(GripperLoadInfo)
);
}
如果你在下载完WMS并运行后,发现它可以满足你的需求,并打算在此基础上进行二次开发,那么你在通过CodeFirst模式新增完数据表后,就可以使用DbFirst模式来生成四层项目的代码文件了:Model+Service+Repository+Controller,当然你也可以手动新建出来这些代码文件。
WMS是通过开放Web Api来支持你进行自动生成四层项目的代码文件的,所以需要先将项目运行起来,此时应用的自宿主服务也就启动了,默认监听端口为9000,此时可以通过浏览器或者Postman等工具访问该接口了,成功后会自动生成四层项目文件,存放生成文件的目录为"C:\my-file"。
代码文件生成接口(GET请求):http://localhost:9000/api/DbFirst/allframefiles
├─Wpf.MvvmLight.SelfHost // UI视图层
│ ├─Common // 存放本项目中用到的通用类
│ │ ├─Enum // 存放枚举类型
│ │ ├─Helpers // 存放帮助类
│ │ ├─Model // 存放实体类
│ │ ├─Services // 存放对外提供服务的类
│ │ └─SocketCommand // 存放SuperSocket服务端处理命令
│ ├─Config // 存放工具相关的配置文件
│ ├─EventBus // 封装了MVVMLight中带有的消息/订阅机制
│ ├─Model // MVVM中的Model层:负责数据实体的结构处理,与ViewModel进行交互
│ │ └─ASChildModel // 子Model(项目Demo)
│ ├─Properties // 项目自动生成,可忽略
│ ├─Resources // 存放系统静态资源
│ │ ├─img // 存放图片资源
│ ├─View // MVVM中的View层:负责前端展示,与ViewModel进行数据和命令的交互
│ │ ├─ASChildView // 子View(项目Demo)
│ │ └─HomeChildView // 子View(项目Demo)
│ ├─ViewModel // MVVM中的ViewModel层:负责前端视图业务级别的逻辑结构组织,并将其反馈给前端
│ │ └─ASChildViewModel // 子ViewModel(项目Demo)
│ ├─x64 // 存放项目在x64平台下的必需的dll
│ └─x86 // 存放项目在x86平台下的必需的dll
├─Wpf.MvvmLight.SelfHost.Api // 对外开放的Api层
│ ├─Controllers // 存放控制器
│ ├─Model // 存放实体类
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.Common // 通用工具层
│ ├─Config // 存放工具相关的配置文件
│ ├─LogHelper // 存放日志帮助类
│ │ └─NLog // 二次封装NLog
│ ├─Properties // 项目自动生成,可忽略
│ └─SocketHelper // Socket帮助类,二次封装SuperSocket
├─Wpf.MvvmLight.SelfHost.Extensions // 扩展层,存放项目相关的扩展插件,暂无内容
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.IRepository // 仓储层抽象接口层
│ ├─Base // 仓储父接口
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.IServices // 业务逻辑层抽象接口层
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.Model // 实体数据层
│ ├─Enum // 存放枚举类型
│ ├─GlobalVariable // 存放全局变量
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.Repository // 仓储层,管理数据持久层
│ ├─Base // 仓储父类
│ ├─DBSeed // 存放种子数据生成类
│ └─Properties // 项目自动生成,可忽略
├─Wpf.MvvmLight.SelfHost.Services // 业务逻辑层,关注业务逻辑
│ └─Properties // 项目自动生成,可忽略
└─Wpf.MvvmLight.SelfHost.Tasks // 任务作业调度层(该层只提供了Quartz使用Demo,待完善)
├─Jobs // 存放各种Job(使用了Quartz)
└─Properties // 项目自动生成,可忽略
目前项目中的可配置项并不算多,后面会逐渐完善。这里主要提一下UI视图层和Common层中的配置文件。
视图层中的App.confg
<connectionStrings>
<add name="SQLiteConnStr" connectionString="URControl.db" />
connectionStrings>
Common层中的NLog.config
<targets async="true">
<target name="seq" xsi:type="BufferingWrapper" bufferSize="1000" flushTimeout="2000">
<target xsi:type="Seq" serverUrl="http://localhost:5341" apiKey="yPEItxPvth4HnynZhg39">
<property name="ThreadId" value="${threadid}" as="number" />
<property name="MachineName" value="${machinename}" />
<property name="Environment" value="Development" />
<property name="Logger" value="${logger}" />
target>
target>
targets>
<rules>
<logger name="*" minlevel="Info" writeTo="seq" />
rules>
使用 Windows Presentation Foundation (WPF),你可以创建适用于 Windows 且具有非凡视觉效果的桌面客户端应用程序。
上面是摘自微软官方对WPF的介绍,其实任何一名工作多年的C# Coder,或多或少可能都会有所听说或了解,我这里也没什么好过多赘述的,给人留下的印象简单点描述可能就是:WPF做出来的界面好看!
相对Winform做出来的桌面应用来说,WPF也确实更容易做出好看的界面,但是对我来说,不仅仅是如此。WPF也让我第一次接触了MVVM,熟悉前端的同学肯定都知道现在流行的三大框架Vue.js、React.js、Angular.js,而它们无一不是用到了MVVM的设计思想。
WMS用到的.NET版本是 .NET Framework4.6.1,相对于 .NET 6.0(最新的LTS版本)来说,4.6.1版本确实有点陈旧了,而且目前 .NET Framework版本也已不再更新了,但是就我目前对工业物联网行业中用到的上位机的了解,它的侧重点是在自动化运行中保持稳定!甚至会考虑的更细,比如程序的执行效率、内存的占用情况等等,所以我在着手做第一个自动化项目之前,一度考虑到使用Winform去完成它,但由于种种原因,我最终还是使用了WPF,并且在和其他项目组成员的实际合作中,定下来使用 .NET Framework4.6.1。
这里我还是想多嘴一下,如果可以的话,建议大家去积极拥抱新技术,并且能在项目中使用它,我觉得这是任何一名Coder都应该有的专业素养(如果你确实喜欢,并且想在这一行业一直做下去的话)。
既然这里说到了MVVMLight,那就简单提一下MVVM吧!MVVM是Model-View-ViewModel(模型-视图-视图模型)的简写。它是一种用于解耦 UI 代码和非 UI 代码的 UI 体系结构设计模式,主要目的是为了分离视图(View)和模型(Model)的耦合,由数据绑定来提供松散耦合,因此使用它可以减少不同类型的代码之间的硬性依赖关系。详细的这里也不再赘述了,有兴趣的可以网上找更多资料去了解它。
MVVMLight是个应用于WPF的轻量化的MVVM框架,它算是历史悠久了,作者也早早地停止了维护,是个较为小众的框架,但应用它的项目却不算少,有些甚至耳熟能详(比如虎牙客户端),这里我不会去讲解它的使用方法,又兴趣的可以参考《利刃 MVVMLight》这篇博文进行学习,这里面说的真的很详细。
除了MVVMLight,另外推荐2个值得大家去学习了解的MVVM框架:MVVM Toolkit和Prism。MVVM Toolkit在一定程度上是对MVVMLight的优化、延申和扩展,而Prism则是一个重型的MVVM框架,提供的功能很强大。
由于项目需求,需要给第三方开放Web接口,而且不方便部署在IIS或其他Web服务器上,所以就产生了通过应用程序来托管Web API的想法。
因为之前并没有做过类似的托管服务,我查阅了很多相关资料,还是有很多的解决方案的。目前官方推荐使用的是OWIN来实现自承载Web Api框架,但我在按照官方资料实现的过程中,遇到了很多问题,前面都一个一个解决了,最终我倒在了"和MVVMLigh中自带的SimpleIoc产生冲突"这个问题上,当然,这其实也是有解决方法的,但是那种方法不利于我日后的开发工作,所以我也就暂时放弃了在项目中使用OWIN,转向用SelfHost去实现托管API。
SelfHost可以实现将一个Web API宿主到一个任意类型的应用程序,包括控制台、Winform、WPF、Windows Service等等,而不局限于IIS。具体的使用方法并不复杂,详细的可以参考项目中Api层中的代码。
对于WMS框架基本使用的介绍算是告一段落了,并没有说的很细,因为我最初的主要目的只是想对自己做的东西有个记录而已,当然也是让使用者能对整个框架有个大概的了解,后面有机会的话我会对框架进行拆分讲解,也想对框架的整个开发过程有个详细的记录。
WMS框架缺陷和待优化完善的地方仍然有很多,欢迎各位大佬进行指教,我自己也会尽力维护下去!