不吹不黑,跨平台框架AspNetCore开发实践杂谈
前言
最近边学边做,初步上手了AspNetCore的开发,对MVC这套熟悉了一下,因为之前没有拿来做过独立项目,都是和别人合作开发,所以前后端分离,我都只做WebApi,而且还是很小的项目(课设级别),生产环境用最多的应该是Python的Django框架,这次我把一个之前做的Django项目用AspNetCore重写一遍,性能提升了不少,C#的性能真不是盖的,AspNetCore这个框架的性能也很不错,榜上有名的(WebApi),虽然MVC排不上名,但是性能依旧甩Django很多,Django每次上线前就做各种性能优化,恐怖,不过性能太好也不行,等会公司觉得工作量不饱和(逃)
ok,既然是杂谈,那也不用把条理梳理得很清楚,我随意列几个方面对比其他框架(Django和Spring之类)聊一聊~
由于我是初学者,对各种概念的理解可能有偏差的地方请各位大佬指正,也欢迎大家一起交流哈哈
依赖注入
对于写习惯Django的我来说,依赖注入以前是很少用到的,刚刚搜了一下,发现Stack Overflow上有一个讨论(Why is IoC / DI not common in Python?)说得不错,给我扫盲了一下,传送门:https://stackoverflow.com/questions/2461702/why-is-ioc-di-not-common-in-python
Python的模块是天生单例模式的,比起Java这种甚至单例模式有多少种实现方式都能进面试题的语言,不知道高到哪里去了,C#好很多,有静态类,不过在开发中还是会以Singleton模式注册到IoC容器中来实现单例~
依赖注入有个很形象的类比,就是把静态语言当成动态脚本语言来用:启动时把一堆东西丢进去IoC容器里,等到要用的时候告诉容器要给你什么,容器就帮你生成,而在容器里面的这堆东西又可以导入别的依赖,这样层层下来相互依赖,如果框架运行过程出问题的话排查起来很痛苦hhh,还要注意避免因为设计问题导致循环依赖等各类问题,所以感觉Django在设计上还是好,生产力是真的高,其他Web框架用得少,除了AspNetCore和Django这些,就用了传统的Spring、Beego和其他小众语言的MVC框架(我甚至用过dart写后台,然并卵),有时间试试新兴的的Vert.x、WebFlux这类,应该会比较好玩~
就这个IoC和DI来说AspNetCore和Spring差不多,功能上差不多,使用方法也差不多,hhh,不过写起来肯定是不如Python畅快的,不过为啥我还要用AspNetCore这种东西呢,因为静态类型语言写起来爽呀,Drf写接口特别快,但是写起来基本靠猜,哈哈哈,感觉这个形容很贴切。最近有个FastApi的看起来不错,据说是100%的类型注解,可以把Python当成静态类型语言来写,但是这种框架太新了,没有经过市场的验证,很难在生产环境用上…
ORM
数据库操作是现在Web框架的核心(误?),我也不知道,反正Web开发基本就是CRUD,整天和数据库打交道是没错的,所以ORM很重要,设计合理好用的ORM可以减少很多工作量,Django为啥受欢迎一大原因就是它的ORM很强大很好用,这应该也是动态语言的优势之一吧。
.NetCore平台上的其他ORM我只用过EF Core和Chloe(官网:https://github.com/shuxinqin/Chloe),这个Chloe也是一个国产ORM,用起来蛮方便的,但是不支持数据库迁移,没办法根据代码生成数据库表,这点还是有点不爽的。EFCore是微软官方的ORM,自然是好用,支持数据库迁移,这个就很方便了,然后其他特点我也总结不出来,因为用得不深,没啥特别的体会。
这次项目我选的ORM是国产的FreeSQL,原因是偶然间在博客园看到作者王婆卖瓜的文章,觉得还不错,然后就拿来用一用,确实挺好用的,可以很轻量一句话完成数据库连接建立,也可以像EFCore那样有各种丰富的功能,而且也支持DB First,这个就很舒服了,这次因为是把Django项目迁移到AspNetCore,所以我打算先用原来的数据库试试看,然后FreeSQL一通DB First之后居然美滋滋的可以用,就更坚定了要继续用下去的信心,哈哈(虽然后面遇到了很多坑,大多是关于多对多关系的,被DjangoORM惯坏了)
FreeSQL官网文档:https://github.com/dotnetcore/FreeSql/wiki
体验下来,FreeSQL对外键(一对多、多对一)、多对多、一对一关系的处理方式还是可以的,通过「导航属性」,跟EFCore应该差不多,但是定义Model的时候如果有外键,还有多定义一个字段存Id,这点感觉有点反人类了,EFCore不用,直接引用对象即可,迁移之后反映到表里就是一个外键Id,不过这个FreeSQL是软外键,引用归引用,关系全都在代码里面处理,不在数据库里面生成外键,这个也有它的好处,甚至可以说是一个优势了,有时候维护表的完整性约束有点麻烦hhh
参考文章:.NET ORM 导航属性到底可以解决什么问题?https://www.cnblogs.com/kellynic/p/13575053.html
然后再小小对比了一下Kotlin的Ktorm,这也是一个优秀的ORM,上次我也小小的试用了一下,挺不错的,除了没有迁移功能没法自动建表,这个Ktorm用起来类似EFCore的体验,同样是外键直接引用就行,不用像FreeSQL那样留一个Id字段来保存,各有利弊吧…不展开了
PS:之前的文章里吐槽了Ktorm之后被作者大佬看到找上来手把手指导我写代码了(逃),有些坑真不是框架的问题,还是自己太菜了啊…
数据库
数据库我用SQLite,反正小项目我全都用这个,性能好,部署方便,虽然有写入锁,但就几个人在用的系统,要啥自行车?
- 记一次 SQLite 性能优化 https://www.isaced.com/post-272.html
- 每天4亿行SQLite订单大数据测试 https://cloud.tencent.com/developer/article/1016993
ViewModel
ViewModel在分层架构中很重要,其实除了ViewModel还有一个叫DTO(Data Transfer Object)的概念,ViewModel和DTO在MVC架构中同属于Model层,DTO也可以叫做Input Model,因为一般作为外部传入数据的对象(顾名思义嘛),然后通常总是在说的Model,其实也可以叫Entity,这些对象是直接对应到数据库中的表,一般在View或者Api中不直接呈现Model,而是呈现ViewModel,因为可能我们会对要输出的数据做一些处理啦,比如增加字段删除字段这些,用Model肯定不行,数据表都是固定的。
同理,在传入数据的时候,和数据表也不一定重合的,所以需要借助DTO,其实和ViewModel没什么严格的界限,你要拿DTO去呈现也行,只是我觉得ViewModel看名字就是拿来呈现的,习惯哈哈。
其实传统的MVC、MVVM模式都已经有点跟不上时代了,我觉得现在的Web应用就得按照DDD(Domain-Driven Design)模式来设计,不过DDD初学有点复杂,概念很多,我也不好乱解释,引用一下知乎的一段回答:
DDD简单说是: 一个项目里面有多个Bounded Context, 譬如说一个是前台面向用户的,一个是后台面向公司内部人员的。每个Bounded Context里面会分为多个aggregate。每个aggregate里面包含了一堆需要保证事务性一致的物体,也就是说从全局来说,每个aggregate都是当作一个整体。常见的例子就是Order(订单)和OrderLine(订单里面的商品)。Entity包括Aggregate root都有唯一标识。两者的区别是aggregate root全局里面有唯一标识,而aggregate 内部其他entity只是在aggregate内部有唯一标识(也许你数据库里面有主键,但是这边是指概念上来说这个唯一标识对全局来说意义不大,只有在aggregate内部意义才大)。另外的value object就是没有标识的物体,他们的意义就在于它的值,你可以想象成比较两个entity是不是同一个只需要判断ID是否相等,而判断value objects需要看里面的每个属性是否一样。
作者:鲍牙叔
链接:https://www.zhihu.com/question/25256772/answer/77940547
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
然后,这么多对象在转来转去,又有很多字段是差不多的,一个个重新赋值显得很傻也根本没必要,这个时候AutoMapper就要用起来了,具体用法不是本文的讨论范围(参考下方列出的官方文档),不过提一点,AutoMapper是可以配置的,有哪些字段不要的可以排除,我在Profile中是这么写的:
public class VideoProfile : Profile {
private readonly List<string> _unmapped = new List<string> {
"HostEnvironment", "Previews", "OverallRating"
};
public VideoProfile() {
CreateMap<Video, VideoViewModel>();
ShouldMapProperty = (property) => !_unmapped.Contains(property.Name);
}
}
把不要的字段放在一个List里面,然后用lambda配置 ShouldMapProperty 就好啦。
参考
- AutoMapper https://docs.automapper.org/en/latest/Getting-started.html
- RESTful+FreeSql+AutoMapper https://luoyunchong.github.io/vovo-docs/dotnetcore/examples/freesql-sample-blog-restful-use-automapper.html#adding-profiles
- FreeSql、AutoMapper处理多对多查询映射 https://blog.csdn.net/XinShun/article/details/104755959
一些关于C#语言的
C#语言我用很久了,但是却几乎没有专门去学习过语法,这门语言,emmm,下限低,上限很高,上手很简单,但复杂度比Java高很多,语法糖很多,所以圈子里的人很多有种高人一等的优越感哈哈,但其实国内的生态是比较差啦,有就是一些培训班啥的在吹,不过国外可以感觉到是比较热门的一个技术,平时遇到啥问题,可能用中文关键词搜不到,但是换成英文可以轻松搜索到很多高质量的答案,只能说国内的技术环境被阿里之类的大厂带偏了,大家都去搞Java了,很多其他好技术和好的语言无人问津,可惜啊……
这次项目也没用到啥高大上的东西,就是泛型、扩展方法、高阶函数这类,用得飞起,贴一小段代码来看看哈哈~
public static IList<TViewModel> ToViewModels<TModel, TViewModel>(
this ISelect<TModel> data,
IService<TModel, TViewModel> service,
int limit = 0
) where TModel : class
where TViewModel : class {
var limitData = limit == 0 ? data : data.Limit(limit);
return limitData
.ToList()
.Select(service.Get)
.ToList();
}
public static IEnumerable<TViewModel> ToSampleViewModels<TModel, TViewModel>(
this ISelect<TModel> data,
IService<TModel, TViewModel> service,
int limit = 0
) where TModel : class
where TViewModel : class {
return data.ToViewModels(service)
.Shuffle()
.Take(limit);
}
这个代码就是把FreeSQL查询数据库的结果一键转换为ViewModel,转换过程是通过Service,功能很简单,但是做成扩展方法然后调用真的不要太爽,减少了n多代码重复,很舒服~
然后C#的高阶函数一开始我有点不习惯,因为之前写习惯python、dart和js,都是map、reduce、filter这些,但是C#的LINQ中却换了个名字,map对应select、filter对应where,这就很像SQL的风格了,我一开始都找不到……
总之C#语言值得好好学一学,对提高工作效率和编程思维是有帮助的!多看书就完事了!
参考资料
几个库
另外还有看到好像蛮不错的几个库,我还没用,目前已经把AspNetCore应用到工作中了,以后应该有机会把这些库用上hhh
- Util应用框架:https://github.com/dotnetcore/Util/blob/master/readme.md
- Masuit.Tools:https://github.com/ldqk/Masuit.Tools
欢迎交流
我整理了一系列的技术文章和资料,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~
不吹不黑,跨平台框架AspNetCore开发实践杂谈的更多相关文章
- 跨平台移动框架iMAG开发入门
iMAG是一个非常简洁高效的移动跨平台开发框架,开发一次能够同一时候兼容Android和iOS平台,有点儿Web开发基础就能非常快上手.当前移动端跨平台开发的框架有非常多,但用iMAG另一个优点,就是 ...
- 浅谈跨平台框架 Flutter 的优势与结构
作者:个推iOS工程师 伊泽瑞尔 一.背景 目前,移动开发技术主要分为原生开发和跨平台开发两种.其中,原生应用是指在某个特定的移动平台上,使用平台所支持的开发工具和语言,直接调用系统提供的API所开发 ...
- 01.html5+phonegap跨平台移动应用开发
一.html5+PhoneGap基础知识 (1)html5介绍 HTML5是用于取代1999年所制定的 HTML 4.01 和 XHTML 1.0 标准的 HTML 标准版本,现在仍处于发展阶段,但大 ...
- 一文读懂跨平台框架 Flutter 的搭建与运行
作者:个推iOS开发工程师 伊泽瑞尔 Flutter是Google推出的跨平台的解决方案,用以帮助开发者在 Android 和 iOS 两个平台开发高质量原生应用的全新移动 UI 框架. 之前我们为大 ...
- .NET 跨平台框架Avalonia UI: 填坑指北(二):在Linux上跑起来了
上一章回顾: .NET 跨平台框架Avalonia UI: 填坑指北(一):熟悉UI操作 本篇将要阐述 包括但不仅限于Avalonia及所有Windows到Linux跨平台开发 的一些注意事项: 一 ...
- 跨平台框架与React Native基础
跨平台框架 什么是跨平台框架? 这里的多个平台一般是指 iOS 和 Android . 为什么需要跨平台框架? 目前,移动开发技术主要分为原生开发和跨平台开发两种.其中,原生应用是指在某个特定的移动平 ...
- uni-app跨平台框架介绍和快速入门
前言: 首先今天主要介绍的是一个多平台的前端框架uni-app,关于多平台的前端框架网上有很多成熟的解决方案比如说Taro,React Native,Flutter等这些都是一些非常优秀的前端跨平台的 ...
- Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...
- Taurus.MVC 微服务框架 入门开发教程:项目部署:6、微服务应用程序Docker部署实现多开。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 开源地址:https://github.com/cyq1162/Taurus.MVC 本系列第一篇:Tauru ...
随机推荐
- 你不可不知的WEB安全知识(第一部分:HTTPS, TLS, SSL, CORS, CSP)
译 原文地址:https://dev.to/ahmedatefae/web-security-knowledge-you-must-understand-it-part-i-https-tls-s ...
- mysql-10-union
#进阶10:联合查询 /* union联合 将多条查询语句的结果合并成一个结果 语法: 查询1 union 查询2 union 查询3 ... 应用场景:要查询的结果来自于多个表,且多个表没有直接的连 ...
- Python练习题 033:Project Euler 005:最小公倍数
本题来自 Project Euler 第5题:https://projecteuler.net/problem=5 # Project Euler: Problem 5: Smallest multi ...
- Python练习题 019:求分数序列之和
[Python练习题 019] 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和. --------------------------------- ...
- Linux系统编程—信号集操作函数
先来回顾一下未决信号集是怎么回事. 信号从产生到抵达目的地,叫作信号递达.而信号从产生到递达的中间状态,叫作信号的未决状态.产生未决状态的原因有可能是信号受到阻塞了,也就是信号屏蔽字(或称阻塞信号集, ...
- 一个Java对象的内存布局
1.对象的创建过程 class loading class linking(verification,preparation,resolution) class initializing 申请对象内存 ...
- Java之线程池解析
线程池 目录 线程池 线程池概述 创建一个线程池并提交线程任务 线程池源码解析 参数认识 构造方法 提交任务 addWorker 执行任务 关闭线程池 线程池概述 什么是线程池 为什么使用线程池 线程 ...
- 安装haproxy
安装依赖 yum install -y gcc pcre pcre-devel openssl openssl-devel 创建依赖账号,并禁止账号登录 useradd -M -s /sbin/nol ...
- 4-K8S 部署Java应用及应用程序生命周期管理
1.在kubernetes中部署应用程序流程 准备项目源码-->编译构建-->产出war包,打包到镜像中-->推送到镜像仓库 获取源代码是开发人员提交代码的代码托管地址,有Git.S ...
- ubuntu 19.10 中防火墙iptables配置
$sudo which iptables /usr/sbin/iptables说明有安装 如果没有安装,那么使用sudo apt-get install iptables 安装. 刚装机,是这个样 ...