WMS—Wpf.MvvmLight.SelfHost
介绍
其实本人之前一直主攻Web前后端的开发,但是由于业务需要,今年开始被分到了公司的自动化项目组搬砖,主要负责上位机的开发。看着项目组中参差不齐的开发模式,也没有具体的便于开发人员使用的项目开发框架,遂产生了设计一种通用开发框架的想法,最终在第一次自动化项目的开发工作中孕育出了WMS(Wpf.MvvmLight.SelfHost)。
项目需求
- 宇宙最强IDE:Visual Studio 2019(推荐)/ Visual Studio 2022(偶尔遇到小Bug)
- .NET版本:.NET Framework 4.6.1
下载
Github: https://github.com/ForeverRG/Wpf.MvvmLight.SelfHost.git
快速了解
项目简介
Wpf.MvvmLight.SelfHost(简称WMS)是一款基于MVVMLight+SelfHost的WPF自动化项目便捷开发框架。
主要特性
- 自动生成代码功能(核心的四层项目类文件)
- 项目层层分明,注重解耦合
- 作为Web服务器,托管Web Api
- 集成常用的第三方库,并对部分进行二次封装,易使用与维护
- 附带自动化项目的业务处理模型
- …
技术选型
1.系统环境
- .NET Framework 4.6.1
2.核心
- WPF
- MVVMLight
- SelfHost
3.日志
- NLog
- Log4Net
- Seq
4.持久层
- SqlSugar
5.视图层
- MaterialDesign
- MahApps
快速开始
- 下载该项目,项目下载完成后,双击Wpf.MvvmLight.SelfHost.sln打开解决方案。
- 首先生成整个解决方案,看是否有出错,无报错后直接F5运行项目即可(注意:设置Wpf.MvvmLight.SelfHost为启动项目)。
- 运行起来后是个WPF项目,内部使用了一个轻量级的MVVM框架——MVVMLight,此外内部还通过SelfHost托管了Web Api,所以该应用也算是个小服务器,默认监听端口为9000。
- 项目中使用的是Sqlite数据库,项目运行起来后会在根目录的DB文件夹自动生成数据库。
- 双击根目录下的批处理文件CreateYourProject.bat,根据提示输入自己想要的项目名称,之后在根目录下会有一个.YourProject文件,里面则是你的项目。
- 项目启动后,点击主界面的"启动"按钮,开始监听TCP Server端口2022,此时点击左侧菜单中的"运行调试",切换到对应界面,点击相应的按钮,即可运行自带的Demo。
代码生成
在开发过程中,项目里其实有很多代码都是重复的,为了提高各位Coder的工作效率,让各位更专注于业务逻辑的开发,于是提供了代码自动生成功能。
CodeFirst
我在上述开始的步骤中有提到过,在项目运行后,根目录会自动生成了数据库文件,这里的自动生成其实就是CodeFirst模式。
- 更改数据库名称。打开Wpf.MvvmLight.SelfHost项目下的App.config文件,可以修改数据库名称,具体配置如下。
<connectionStrings>
<add name="SQLiteConnStr" connectionString="URControl.db" />
</connectionStrings>
- 新增实体类。在Wpf.MvvmLight.SelfHost.Model项目下新增自己想要的实体类,可以参考已有的实体进行添加,更详细的特性配置,可以参考SqlSugar官方文档进行学习。
- 自动创建表。在Wpf.MvvmLight.SelfHost.Repository项目下的DBSeed文件中,打开SQLiteDbContext.cs进行实体装载,在InitDB方法中添加新增的实体类型参数,添加完毕后再次启动应用,此时打开数据库,你就会发现里面新增了一个表,而那个表就是根据你新增的实体自动生成的。
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)
);
}
DbFirst
如果你在下载完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
- 关于数据库的配置:
<!--sqlite数据库-->
<connectionStrings>
<add name="SQLiteConnStr" connectionString="URControl.db" />
</connectionStrings>
- 关于SocketServer的配置:如果是通过配置启动SocketServer的话,就需要进行相关的配置,详细的配置和使用说明请参考官方文档
Common层中的NLog.config
- 关于NLog.config的配置,输出规则和格式等内容请参考官方文档,另外项目中集成了Seq日志服务,可以将日志输出到seq,使用者可以通过搭建seq服务,然后直接在系统中查看相关日志即可,具体配置项:
<!--seq日志服务-->
<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>
核心技术
WPF
- 介绍
使用 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都应该有的专业素养(如果你确实喜欢,并且想在这一行业一直做下去的话)。
- 优点
- 界面视觉效果好,用户交互友好。
- MVVM的设计思想让UI和业务逻辑进一步解耦合。
- 提供了更广泛的应用开发功能,包括应用模型、资源、控件、图形、布局、数据绑定、文档和安全性。
MVVMLight
- 介绍
既然这里说到了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框架,提供的功能很强大。
- 优点
- 轻量化的MVVM框架。
- 自带简易的Ioc框架SimpleIoc,用于视图模型注入。
- 提供了Messenger,一种消息发布/订阅模式,用于通信的解耦合。
SelfHost
- 介绍
由于项目需求,需要给第三方开放Web接口,而且不方便部署在IIS或其他Web服务器上,所以就产生了通过应用程序来托管Web API的想法。
因为之前并没有做过类似的托管服务,我查阅了很多相关资料,还是有很多的解决方案的。目前官方推荐使用的是OWIN来实现自承载Web Api框架,但我在按照官方资料实现的过程中,遇到了很多问题,前面都一个一个解决了,最终我倒在了"和MVVMLigh中自带的SimpleIoc产生冲突"这个问题上,当然,这其实也是有解决方法的,但是那种方法不利于我日后的开发工作,所以我也就暂时放弃了在项目中使用OWIN,转向用SelfHost去实现托管API。
SelfHost可以实现将一个Web API宿主到一个任意类型的应用程序,包括控制台、Winform、WPF、Windows Service等等,而不局限于IIS。具体的使用方法并不复杂,详细的可以参考项目中Api层中的代码。
- 优点
- 让应用程序实现自宿主,托管Web Api,方便处理外部发送过来的请求。
- 将 Web 应用程序与服务器分离,免去了部署Web Api的步骤。
项目进度
- 使用仓储+服务+接口的形式封装框架
- 使用ORM组件SqlSugar,封装数据库操作
- 实现项目启动后,自动生成种子数据
- 实现自动生成项目中的四层文件
- 封装Wpf.MvvmLight.SelfHost.Template项目模板,一键新建项目
- 支持多种数据库的使用和切换
- Web Api集成身份认证于鉴权框架
- Webp Api集成Swagger
写在最后
对于WMS框架基本使用的介绍算是告一段落了,并没有说的很细,因为我最初的主要目的只是想对自己做的东西有个记录而已,当然也是让使用者能对整个框架有个大概的了解,后面有机会的话我会对框架进行拆分讲解,也想对框架的整个开发过程有个详细的记录。
WMS框架缺陷和待优化完善的地方仍然有很多,欢迎各位大佬进行指教,我自己也会尽力维护下去!