零基础ASP.NET Core WebAPI团队协作开发

相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了。网上也有很多介绍这方面的文章。我这里提这个是因为接下来我要分享的内容和这个有些关联。

随着前端应用场景的繁荣,用户体验需求的提高,原先传统的后端渲染页面返回给前端展示的模式面临挑战。后端工作除了处理数据逻辑还得适应界面UI的业务,越来越不堪负重。前端的重要性逐渐体现出来,在这种情况下使用前后端分离模式开发的逐渐增多。

前端框架(比如Vue/Angular/React)的发力,大厂的推广使用,前后端分离已经很成熟。包括传统信息化这块以前使用传统WebMVC模式的开发的BS应用有些都逐步转为前后端分离模式。特别是开发人员分工之后专注做好各自的工作,效率更高,做出来的产品也就更好。

一、应用场景

1、浏览器端(Vue/Angular/React)+服务端API

2、桌面客户端(mfc/winform/wpf)+服务端API

3、移动客户端(各种App/App内置浏览器)+服务端API

4、其他终端(大数据展示平台/报表展示平台)+服务端API

客户端越来越强调轻量化,交互体验,不在满足于能用。服务端端只管提供API数据,这样业务逻辑大多在服务端处理,随着需求增加服务端的模块会越来越多。但是有些接口是共用的,有些是根据业务变动的,还有的API新旧版本过渡更新替换等等是服务端api要考虑的事情。设计好API开发框架面灵活应对这么多场景就很有必要了。

原先可能会做一个单体式应用,把所有用到的接口都加进去。但这样粒度很粗,如果某个场景下只使用了部分接口,那也得把这整个应用部署,无法做到按需添加。还有就是可能要修改其中部分方法,需要整体重新编译发布。这都存在可能影响其他模块的风险。

服务端任务量大了,怎么分工?这个时候单体明显已经不适用了。这里就引出了微服务。对微服务可能每个人有不同的理解,但有一点是有共识的,就是把一个大的单体式应用根据功能模块拆分,这样粒度细分之后很多接口就可以共用。之后的修改增加都是可以按需发布部署,局部出现问题不会影响整体。

这个服务的粒度怎么拆分也是需要慎重考虑的问题。除了功能拆分还得考虑人员匹配。

案例场景:一个系统有10个子系统(模块),每个子系统(模块)又有10个功能,每个功能再具体又可能有20个左右的方法代码。

这个案例,最后大概有2000个方法代码。

如果开始安排10人的团队开发,中途因为项目紧急再增加了10个人进来,总共变成了20人,项目组怎么做才能快速适应这种人员变动。

有时候不是人越多越能做好事情,在人员增加情况下除了增加沟通协调成本,实际情况会遇到新加的人参与进来的门槛很高,不能快速着手展开工作,有时候还会出现不知道从何入手的困境。这就是因为拆分的不合理,任何的改动可能会影响到他人。这样虽然为了赶进度加人了,但实际的效果却不是很理想。

二、功能拆分分析

怎么拆分这有两个极端例子

1、粒度最粗,全部在一个解决方案(极端例子,类似单体式应用,适合一人开发)

2、粒度最细,细分到每个方法一个解决方案(极端例子,实际肯定不会这样做)

实际项目中功能拆分就是在这两个极端情况之间找适合的平衡点。具体拆分到多大的粒度,这个就只能是根据具体项目情况具体分析了。但是微服务可能是建议往细的方向拆。

如果是项目型的会发现如果拆的太细,上线一套系统要带N个接口,运维实施都很麻烦;如果是做平台型的产品可能就是有限的几套系统,不会随着项目铺开太多定制化。也就没有了项目型里面的经常部署实施等繁琐的问题。

比如上面的案例,一般都是先根据子系统拆分,具体到每个子系统,有一人或多人开发也有后期临时加入的情况。每个子系统一套接口还是比较合适的。

实际情况项目型比较多,考虑实施运维情况拆分的粒度不会太细,让实施去部署太多业务接口会把他们逼疯。如果有和我类似情况的下面的方案提供了一种解决办法。开发时候可以横向任意扩展,新加入的人员分配任务清晰,不用担心有耦合冲突。发布部署也不会因为粒度太细,增加部署工作量。总结就是插件式开发,微服务部署。

我们都知道vs里面建立一个解决方案,两三个开发人员在同一个解决方案里面开发,只要协调好还行,如果再加入人员,参与的开发人员一旦多了,就算分工好做各自模块,但还是会存在一个些冲突,比如增加文件,增加引用等等都会引起项目文件或者解决方案文件冲突问题。而且这种情况代码权限还不好细分控制。

最好的方式是每个开发人员做的事情都在自己的解决方案里面,只要是公共使用的引用协调好大家使用统一的版本,其他的自己完全可控,完全不用担心影响他人,或者他人的修改影响自己。

大家可以看下这个 github上面dotnet基础类库,如图1。

图1

这是dotnet基础库的源码,每个基础类库都是单独一个解决方案维护,随便点一个进去看下,如图2

图2

每个类库都有独立解决方案文件。

微软肯定有更好的方式去管理,但从这里可以看出,独立开发维护的优势。

三、接口项目准备

前面分享过一篇《零基础ASP.NET Core MVC插件式开发》的文章,那边文章其实也就是强调团队开发的时候能做到尽量独立,可以横向扩展,项目灵活变动增加开发人员可以快速参与,开发之后能汇总到一个个的子系统,最后完成整体开发。在这里API的开发也可以使用类似方案,因为API没有视图部分,处理起来比MVC简单。

接下来重点介绍该方案在API开发中的使用。开始这部分内容之前先简单介绍我这边API项目开发总结的两个共性问题:

1、使用swagger显示API文档(nuget 引用 Swashbuckle.AspNetCore)

因为API是没有试图的,为了可视化,以及方便测试,使用swagger作为API的展示界面。具体使用看下面提供的demo代码

2、使用版本控制API版本号(nuget 引用Microsoft.AspNetCore.Mvc.Versioning)

版本控制对API也是同样重要,看BAT大厂提供的API都是有版本控制的,要向他们看齐。实际应用中,程序不可能维持一套最新,有时候新旧版本需要过渡,所以需要有版本来区分。这里使用微软提供的版本控制。具体使用看下面提供的demo代码

这两个使用这里就不细说了,穿插下面主题做些简单介绍,具体看案例demo就可以。

四、接口插件式开发

回到我们的主题,这里重点介绍下一个子系统(模块)任务拆分与人员分工

项目组接下一个项目,一般有个开发组长,着手模块划分并且开发任务分工

组长(公共部分接口+核心功能模块接口)

组员1:细分的模块插件1接口

组员2:细分的模块插件2接口

组员3:细分的模块插件3接口

......

......

对于的解决方案结构,具体命名自己可以根据喜好自己自定义。

Agile.ModuleName.API  如下图3

Agile.ModuleName.Plug1.API 图下图4

Agile.ModuleName.Plug2.API

Agile.ModuleName.Plug3.API

......

......

图3

图4

Demo使用的是vs2019,Asp.net core 2.1

注意:如果一个模块里面接口比较多,一个解决方案里面不适合团队开发。所以对这种接口功能比较多,拆成各个插件方便团队开发,最后发布的时候合并到一起。但是如果这个模块接口不是很多,就没必要过度设计为了插件化而拆开。

每个独立开发的都是vs里面建立的标准ASP.NET Core WebAPI项目,这里主项目和各个插件项目没有从属关系,完全平等API项目开发,最后只是可以汇合到主项目作为一个站点发布交付。各自独立调试运行各自开发功能模块,测试没问题发布汇总到主项目,部署运行,之后哪个接口问题只需要找到对应的模块修改,完全隔离开,不用担心修改会影响其他正常使用的模块。

主项目解决方案结构,如图5

图5

v1,v2里面的是有版本控制的,放在外面的就不需要版本控制。

还有Extensions文件夹里面两个类也是为了版本的显示做处理,具体看Startup.cs里面代码,如图6

图6

搭建好之后,主项目运行,选择v1版本显示如图7

图7

如果选择v2,显示如图8

图8

通过上面两个切换,应该看到不管选择v1还是v2下面不受版本控制的都会显示。

如果把图4的代码注释掉,看下运行效果,如图9

图9

显示就这样,不能根据swagger选择,直观的显示是v1还是v2。这个就是RemoveVersionFromParameter和ReplaceVersionWithExactValueInPath两个类的作用。

这两个类的代码如下

public class RemoveVersionFromParameter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
if (operation.Parameters.Count > )
{
var versionParameter = operation.Parameters.FirstOrDefault(p => p.Name == "version");
operation.Parameters.Remove(versionParameter);
}
}
} public class ReplaceVersionWithExactValueInPath : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
swaggerDoc.Paths = swaggerDoc.Paths
.ToDictionary(
path => path.Key.Replace("v{version}", swaggerDoc.Info.Version),
path => path.Value
);
}
}

到这里主项目API运行正常,接下来看下插件项目API。

插件1项目结构,和主项目类似,如图10

图10

单独运行下这个插件1项目,效果如图11

图11

这里作为插件API项目同样有一点要注意,不要出现和其他插件或者主项目同名的路由(version,controller,action三个完全一样,分工之后各自命名规范估计这种情况也不会出现,主要还是注意避免合并之后路由重名问题)。

这里先把插件1编译的dll放到主项目的运行目录来,如图12

图12

并且在主项目的Startup.cs里面增加这段代码,如图13

图13

运行看下效果,如图14

图14

汇合成功,插件1的API能展示出来,测试也正常,测试就不截图了。

同理,插件1,插件2...等等也是一样处理。开发阶段,各自开发的功能都是可以独立调试运行的。有没有主项目对各自开发的不影响。

五、问题总结

 

如果插件项目里面引用了一个第三方的程序集,如图15

图15

引用一个测试类库,在Plug1NoVerController的Get方法里面写一个测试代码,如图16

图16

在插件项目单独测试,运行正常。

再把插件1相关文件拷贝到主项目,这时候多了个插件项目自己引用的OtherLib.dll,如图17

图17

正常运行,如图18

图18

测试下刚才插件1里面用到OtherLib类的接口,看效果如图19

图19

汗,居然报错了,提示FileNotFoundException,但是看上面的错误信息截图提示找不到OtherLib.dll文件。OtherLib.dll这个文件明明在这个目录有的。查了相关资料都说是.net core的加载机制变了,但还是没理解透彻,不知道.net core3.0会不会解决这个问题。希望有大神看到可以解惑下这个问题。不过这里我使用一种方式可以解决这个报错,在主程序这里加这段代码。在注册插件项目之前,遍历所有dll,做一次加载就可以了。如图20

图20

需要在注册插件之前,把所有dll文件这样加载一遍,就可以了。

再运行,测试就正常了,如图21

图21

 

 

六、发布运行

各个独立开发的插件API,各自独立开发调试正常之后,发布出来。

好了,插件1,插件2...等等各自都开发好了,各自模块调试没问题,最后汇总到主的项目来,基本也就没什么问题了,并且还可以作为一个站点部署。

这里的一个站点只是一个接口服务,不要理解成一个系统就这一个接口服务,虽然可以这样做,但不建议,部署还是各个子系统一个服务,这样数量也不会很多。这里是指在开发阶段对一个子系统(模块)的N个接口做开发方面的分工独立开发调试。

子系统(模块)有N个接口,开发分工如下:

主插件,插件1,插件2,插件3...

全部汇总到主插件的发布目录,或者手动拷贝,最后提供一个完成的子系统接口发布版本,目录如图22

图22

同样命令行运行,或者宿主到iis,这里命令行运行,如图23

图23

浏览器打开,如图24

图24

直接swagger测试各个接口,正常。

独立插件化开发,微服务发布部署。

希望你看了之后有点收获,代码程序下面附件提供

Demo程序

零基础ASP.NET Core WebAPI团队协作开发的更多相关文章

  1. 零基础ASP.NET Core MVC插件式开发

    零基础ASP.NET Core MVC插件式开发 一个项目随着业务模块的不断增加,系统会越来越庞大.如果参与开发的人员越多,管理起来也难度也很大.面对这样的情况,首先想到的是模块化插件式开发,根据业务 ...

  2. Asp.net core WebApi 使用Swagger生成帮助页

    最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效 ...

  3. Asp.net core WebApi 使用Swagger生成帮助页实例

    最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效 ...

  4. 第十九节:Asp.Net Core WebApi基础总结和请求方式

    一. 基础总结 1.Restful服务改造 Core下的WebApi默认也是Restful格式服务,即通过请求方式(Get,post,put,delete)来区分请求哪个方法,请求的URL中不需要写方 ...

  5. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  6. ASP.NET Core WebApi基于Redis实现Token接口安全认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebSer ...

  7. asp.net core webapi之跨域(Cors)访问

    这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...

  8. Asp.Net Core WebApi学习笔记(四)-- Middleware

    Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...

  9. ASP.NET Core WebAPI中的分析工具MiniProfiler

    介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...

随机推荐

  1. WPF 遍历 控件

    比较简单的方式是 在设计一个画面时 先添加一个grid 或其他的布局控件 确保要遍历的控件都在这个Grid中时就可以这么写 foreach (UIElement uie in Grid.Childre ...

  2. 【全面解禁!真正的Expression Blend实战开发技巧】第三章 从最常用ButtonStyle开始 - TextButton

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第三章 从最常用ButtonStyle开始 - TextButton 在实际项目中,使用blend做的最多的一定是各种自定义But ...

  3. String内存结构

    var s: AnsiString; begin s := '1234567890'; showmessage(s); end; 变量s的内存结构为A8 03 01 00 FF FF FF FF 0A ...

  4. SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)

    原文:SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容(C ...

  5. WPF如何判断PNG中的点是透明的

    最近想用WPF做个空战游戏,其中就要解决子弹是否击中飞机的问题.这里面飞机用了PNG图片,大家都知道飞机是不规则图案,如何判断子弹碰撞成了一个难题. 好在我在网上找到了一个可以获取bitmap像素点颜 ...

  6. 职业规划 - DREAM START

    前言 最近面试了好多公司,得出一个结论:做一份详细的计划.一个程序员,不只是写写代码这么简单的事,一种更高的境界则是在代码中.系统的设计中,能找到人生的意义,简单说就是生活的道理.我一直认为:当你在一 ...

  7. 零元学Expression Blend 4 – Chapter 20 以实作案例学习Childwindow

    原文:零元学Expression Blend 4 – Chapter 20 以实作案例学习Childwindow 本章将教大家如何运用Blend 4内建的假视窗原件-「ChildWindow」 Chi ...

  8. mysql数据库同步系统otter部署实践(中国与欧洲同步)

    otter的介绍就不说了, 自己去看官网https://github.com/alibaba/otter/wiki 本系统中, 中国的服务器部署在阿里云上, 欧洲服务器部署在亚马逊上, 由于阿里云的网 ...

  9. Android无布局文件下自定义通知栏notification的 icon

    在开发项目一个与通知栏有关的功能时,由于自己的项目是基于插件形式的所以无法引入系统可用的布局文件,这样无法自定义布局,造成无法自定义通知栏的icon. 在网上也有一种不用布局文件更换icon的方法,但 ...

  10. web开发常用正则表达式

    整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$只能输入数字:"^[0-9]*$".只能输入n位的数字:"^\d{n}$".只能输入至少n位的数 ...