asp.net core系列 71 Web架构分层指南


一.概述

  本章Web架构分层指南,参考了“Microsoft应用程序体系结构指南”(该书是在2009年出版的,当时出版是为了帮助开发人员和架构师更快速,更低风险地使用Microsoft平台和.NET Framework设计和构建有效,高质量的应用程序)。虽然已过去十年了,技术架构已更新(如流行的DDD/CQRS模式,微服务,容器),但web分层思想还是一样可取,下面是一个“传统N分层设计”架构图,该架构在2010年左右是最流行的,包括了表现层presentation,服务层services,业务层business,数据访问层data,横切关注点cross,如下所示:

640?wx_fmt=png

  对比传统多层或三层.net web架构,下图是当前流行的.net web微服务架构,在web程序分层之上还包含了容器,web api网关,各服务对应的数据存储(sqlserver,redis,mongoDB),web程序有web api并结合应用了DDD\CQRS分层模式,以及系统各种中间件。

640?wx_fmt=png

  下图是一个订单微服务站点,包含了简化的cqrs分层,蓝色长方格是表示cqrs分层的职责,包括了查询 Queries viewModels和命令Command Domain-Model以及上层的应用服务层Application,如下所示

640?wx_fmt=png

  1.1 逻辑分层设计架构类型

    (1) 最传统的分层是经典三层设计,包括表现层,业务层,数据层.

    (2) 基于服务的解决方案SOA,公开应用程序业务功能的服务层,服务层在业务层之上。

    (3) 基于领域驱动设计的DDD\CQRS分层模式

    (4) 微服务架构。

     这4种web分层架构是不断的演化改变 ,每一种分层架构并不是独立的思想,它包含了演化之前的架构分层思想。从以前三层架构到现在的微服务架构,是适应每个时代互联网业务实现的需求。

功能

SOA

微服务

组件大小

大块业务逻辑

单独任务或小块业务逻辑

耦合

通常松耦合

总是松耦合

公司架构

任何类型

小型、专注于功能交叉团队

管理

着重中央管理

着重分散管理

目标

确保应用能够交互操作

执行新功能、快速拓展开发团队

二.Web分层设计步骤

  1.分层策略
    (1)分层粒度是确定分层策略的关键第一步.
    (2)在逻辑分层中, 多层是在同一进程中运行,这可以利用更高性能的通信机制。例如通过组件接口直接调用。必须小心保持层之间的封装和松散耦合。
    (3)在物理分层中,确定合适的通信机制,该机制考虑到通信延迟并保持之间的松散耦合。
    (4)多层中,考虑它们之间如何相互影响,将确保性能和灵活性之间的良好平衡。

  2.确定需要层
    最常用的方法是将表现层,服务层,业务层和数据访问层功能分离到单独的层中。某些应用程序还引入了各种组件像缓存、日志、消息队列等。

  3.决定如何分发各层和组件
    对于web体系架构,一般都是在一个物理层,只有在必要时,才应在不同的物理层上分布层和组件。这是实现分布式部署的常见原因包括安全策略,物理约束,共享业务逻辑和可伸缩性。

  4.确定是否需要折叠层
    一般规则是您应始终将功能分组到层中。在某些情况下,一个层可以充当代理或传递层,提供封装和松散耦合,而不提供大量功能。但是,通过分离该功能,您可以稍后对其进行扩展,而对设计中的其他层几乎没有影响,如:应用服务层。

  5.确定层之间引用的规则
    在分层策略时,您必须定义层如何相互交互的规则(交互是指:各层引用的关系)。指定交互规则的主要原因是最小化依赖性并消除循环引用。因此应该遵循以下方法之一:
    (1)自上而下的交互
      较高级别的层可以与下面的层交互,但是较低级别的层不应该与上面的层交互。此规则将帮助您避免层之间的循环依赖关系,以及要降低层之间的依赖性。
    (2)严格的互动
      每个层必须仅与下面的层进行交互。此规则将强制严格分离关注点,其中每个层仅知道下面的层。此规则的好处是对层界面的修改只会影响上面的层。如果您正在设计一个将随着时间的推移进行修改以引入新功能并且您希望最大限度地减少这些更改的影响的应用程序,或者您正在设计可能分布在不同物理层上的应用程序,请考虑使用此方法。
    (3)松散的互动
      较高级别的层可以绕过层直接与较低级别的层交互。这可以提高性能,但也会增加依赖性。换句话说,对较低级别层的修改可以影响上面的多个层。

    下图是一个示例:该web架构示例是使用了 cqrs 模式,涉及到了事件源es, 事件源实现本因该分离到命令域和查询域, 而项目中应用服务层直接引用了底层数据访问层Dapper(绕过了领域层),  这样底层Dapper接口方法的修改或换成EF将影响顶层应用服务层,这属于第三种"松散的互动"。 应该推荐使用第一种自上而下的交互。

640?wx_fmt=png

  6.确定跨领域问题
    定义层后,必须标识跨越层的功能。此功能通常被描述为横切关注点,包括日志记录,缓存,验证,身份验证和异常管理。确定应用程序中的每个横切关注点非常重要,并设计单独的组件以尽可能地管理这些问题。此方法可帮助您实现更好的可重用性和可维护性。
    如下图所示:NLog与Redis是具体实现组件,实现了Common层中的日志和缓存接口,Common层就是横切组件,是跨层可重用的。像Ioc也是横切组件。下图层的名称没有标识跨越层的功能,如果是GFNetCore.Infra.CrossCutting.IoC 这样命名会更好。

640?wx_fmt=png

  7.定义层之间的接口
    为层定义接口时,主要目标是强制层之间的松散耦合。这意味着层不应暴露另一层可能依赖的内部细节。相反,层的接口应设计为通过提供隐藏层内组件细节的公共接口来最小化依赖性。这种隐藏称为抽象,有许多不同的方法来实现它。以下设计方法可用于定义层的接口:

    (1)抽象接口
      通过定义抽象基类或接口类来实现,该类充当具体类的类型定义。该类型定义了一个公共接口,该层的所有使用者都使用该接口与该层进行交互。这是一种面向接口编程,例如:表现层调用应用服务层的接口。表现层在CustomerController控制器中如下所示(通过依赖注入后,构造方法来实例):

     //表现层调用应用服务层ApplicationService
private readonly ICustomerAppService _customerAppService;

public CustomerController(ICustomerAppService customerAppService,
INotificationHandler<DomainNotification> notifications) : base(notifications)
{
_customerAppService = customerAppService;
}

      但在项目中,为了简化开发量,表现层调用应用服务层的实现类(违反了面向接口编程)。表现层在CustomerController控制器中如下所示:

        //调用应用服务层ApplicationService
private readonly CustomerAppService _customerAppService = null;

//日志对象
public readonly ILoggerEX _logger;

public CustomerController(INotificationHandler<DomainNotification> notifications,
ILoggerEX logger,
CustomerAppService customerAppService)
: base(notifications)
{
_customerAppService = customerAppService;
_logger = logger;
}

    (2)依赖倒置

      这是一种编程风格,是面向接口编程的实现,依赖倒置的应用如:DDD\CQRS, 层依赖于层接口,而不是层依赖于另一个层的实现。依赖注入模式是依赖性反转的常见实现。依赖性反转方法提供了灵活性,可以帮助实现可插入设计,因为依赖性是通过配置而不是代码组成的。它还可以最大化可测试性,因为您可以轻松地将具体测试类注入到设计的不同层中。

      依赖性是通过配置的,如下代码所示,由CommandRepository类来实现ICommandRepository接口:

        services.AddScoped<ICommandRepository<CommandModels.Customer>, CommandRepository<CommandModels.Customer>>();
services.AddScoped<IQueryRepository<QueryModels.Customer>, QueryRepository<QueryModels.Customer>>();

    (3) 基于消息

      可以使用基于消息的通信来实现接口并提供层之间的交互,.net技术如:wcf, web services, msmq它们支持跨物理和进程边界的交互(以xml的soap格式传输),但这是对于09年流行的web架构。现在基于消息多数用web api技术,是面向微服务开发(以json的rest api)。

 参考资料

   分层应用程序指南 

原文链接:https://www.cnblogs.com/MrHSR/p/11272400.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#高级语法之泛型、泛型约束,类型安全、逆变和协变(思想原理)

一、为什么使用泛型&#xff1f;泛型其实就是一个不确定的类型&#xff0c;可以用在类和方法上&#xff0c;泛型在声明期间没有明确的定义类型&#xff0c;编译完成之后会生成一个占位符&#xff0c;只有在调用者调用时&#xff0c;传入指定的类型&#xff0c;才会用确切的类型…

谈自由,ASP.NET Core才是未来?

首先我要说一下自己对自由的理解&#xff1a;自由是我可以选择不干什么&#xff0c;但我要保留我可以干什么的可能性。比如说我现在只有一个码农的角色&#xff0c;但我仍然要保留可以扮演其他角色的可能&#xff0c;比如成为一个作者&#xff0c;当我写下文章的时候已经是了&a…

今天,全网曝光这几个公众号

有人统计过&#xff0c;我们平均每天花在看内容上的时间是5-6小时与其每天被各种看过就忘的内容占据时间不如看点真正对你有价值的信息下面小编为你推荐几个高价值的公众号&#xff0c;这些公众号都是专注.NET技术它们提供的信息能真正提高你生活的质量当你迷茫的时候刷刷这些大…

.NET Core 小程序开发零基础系列(1)——开发者启用并牵手成功

最近几个月本人与团队一直与小程序打交道&#xff0c;对小程序的实战开发算比较熟悉&#xff0c;也因一些朋友经常问我各种小程序问题&#xff0c;无不能一一回答&#xff0c;想了很久&#xff0c;决定还是空余时间来写写文章吧&#xff0c;偶尔发现一个人安静的时候写文章特爽…

学习笔记之12个月提升计划

Java世界博大精深&#xff0c;有太多的东西要学。如果一头扎进去&#xff0c;很可能会淹没在Java技术的海洋里。于是&#xff0c;最近一直在思考列一个提纲&#xff0c;作为高级工程师到资深、再到架构之路的路标。 学习笔记一栏&#xff0c;即为本计划的博客记录。将自己的计划…

从“梁漱溟:思考问题有八层境界”所联想到的

最近一段时间以来写的文章比较少了&#xff0c;这固然是有一些客观原因&#xff0c;但确实有我不可说的一些自我反省和认识等主观因素。记得8月初有一次友人聚餐&#xff0c;席间有朋友聊到公众号的运营心得体会&#xff0c;其中有一条是&#xff1a;避免粉丝减少的黄金法则之一…

程序员过关斩将--cookie和session的关系其实很简单

喜欢就点关注吧!月高风下&#xff0c;下班路上....菜菜哥&#xff0c;告诉你一个秘密&#xff0c;但是不允许告诉任何人这么秘密&#xff0c;你有男票了&#xff1f;~不是&#xff0c;昨天我偷偷去面试了&#xff0c;结果挂了这不是好事吗&#xff0c;上天让公司留住你.....好吧…

.NET导出Excel的四种方法及评测

前言导出Excel是.NET的常见需求&#xff0c;开源社区、市场上&#xff0c;都提供了不少各式各样的Excel操作相关包。本文&#xff0c;我将使用NPOI、EPPlus、OpenXML、Aspose.Cells四个市面上常见的库&#xff0c;各完成一个导出Excel示例。然后对其代码风格和性能做一个横向比…

[2021.1.27多校省选模拟10]染色(min-max容斥/二项式反演)

[2021.1.27多校省选模拟10]染色 突然发现我对概率期望的理解不是很好。。。 部分分1&#xff1a;可以直接进行状压dp&#xff0c;然后按照题意模拟即可。 部分分2&#xff1a;首先可以发现这个问题是min_max容斥形式&#xff0c;然后对于min(T)的问题&#xff0c;我们将问题转…

[2021.1.27多校省选模拟10]跑步(线段树合并)

[2021.1.27多校省选模拟10]跑步 经典的树上启发式合并题目&#xff0c;维护对应子树的从当前点到子树内一个节点这个链待定&#xff0c;其他部分已经确定的方案数&#xff0c;这个东西按照对应点到根节点的路径点权和为下标存在一个权值线段树中&#xff0c;然后维护这个权值线…

ASP.NET Core 双因素验证2FA 实战经验分享

必读本文源码核心逻辑使用AspNetCore.Totp&#xff0c;为什么不使用AspNetCore.Totp而是使用源码封装后面将会说明。为了防止不提供原网址的转载&#xff0c;特在这里加上原文链接&#xff1a;双因素认证双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起…

结合“性能监视器” 排查、处理性能瓶颈导致应用吞吐率等指标上不去的问题...

双11备战前夕&#xff0c;总绕不过性能压测环节&#xff0c;TPS 一直上不去 / 不达标&#xff0c;除了代码上的问题外&#xff0c;服务器环境、配置、网络、磁盘、CPU 亦是导致性能瓶颈的重要一环&#xff0c;本文旨在分享最近项目性能压测过程中的排查经验&#xff0c;文中的表…

秒半价,限四天!Vostro极致轻薄全能本,助你全能全开!

在信息化时代&#xff0c;电脑就是你工作和创业的“合伙人”&#xff01;每天比别人多处理几件任务、每天比别人快20分钟&#xff0c;每天比别人少重启和崩溃几次&#xff0c;日积月累获益多到算不过来&#xff01;小编四处打探&#xff0c;有三款王者电脑重磅优惠&#xff0c;…

【活动】侬好上海,Microsoft Reactor来啦

在美国纽约、旧金山和雷德蒙德&#xff0c;在英国伦敦&#xff0c;在澳大利亚悉尼&#xff0c;在以色列特拉维夫&#xff0c;分别都有这样一处专为开发者打造的宝地&#xff0c;在这些地方&#xff1a;❖ 经常举办各种免费的技术讲座&#xff0c;与大家分享最新技术和产品❖ 频…

A. [2021.1.29多校省选模拟11]最大公约数(杜教筛/数论)

A. [2021.1.29多校省选模拟11]最大公约数 这是一个杜教筛的经典题目&#xff0c;最后我们只需要筛一下1∗xμ(x)1*x\mu(x)1∗xμ(x)这个函数的前缀和即可&#xff0c;然后看到有111这个函数&#xff0c;我们下意识应该想到的就是μ\muμ&#xff0c;然后又有xμ(x)x\mu(x)xμ(x…

.NET Core 小程序开发零基础系列(2)——小程序服务通知(模板消息)

基于上一篇文件“.NET Core 小程序开发零基础系列&#xff08;1&#xff09;——开发者启用并校验牵手成功”的反映&#xff0c;个人觉得效果很不错&#xff0c;大家对公众号开发还是有很大需求的&#xff0c;同时也收到了很多同学的问题&#xff0c;后面我也会通过实战性文章慢…

[PowerShell]人人都值得学一点PowerShell实现自动化(2)有哪些可用的场景及方式?

部分读者反应太多知识要学了&#xff0c;学完一轮又一轮&#xff0c;笔者也不想单单为了制造学习而学习&#xff0c;所有Excel催化剂所发布的内容&#xff0c;都是笔者所亲自使用到的&#xff0c;当然很多领域也没有深挖到很底的程度。PowerShell使用场景虽然说PowerShell也是在…

[2021.1.13多校省选模拟2]T1(动态规划/轮廓线dp)

[2021.1.13多校省选模拟2]T1 一个经典的轮廓线dp&#xff0c;可以发现一定可以找到一条轮廓将这个图形分开&#xff0c;然后使得左半部分由左边处理&#xff0c;右半部分由右边处理&#xff0c;然后我们只需要处理这个折线即可&#xff0c;具体实现需要处理前缀和的前缀最大值&…

[PowerShell]人人都值得学一点PowerShell实现自动化(1)在VisualStudio上使用PowerShell...

最近学PowerShell的知识比较多&#xff0c;也开始有一点点可以分享的知识给大家输出&#xff0c;学一门语言&#xff0c;理当首先找准一个好用的IDE来帮助我们提高学习效率&#xff0c;本文给大家介绍如何在宇宙第一的IDE-Visual Studio上写PowerShell脚本。关于PowerShell的基…