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

  • 时间:
  • 浏览:0
  • 来源:极速快3_快3投注网_极速快3投注网

一.概述

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

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

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

  1.1 逻辑分层设计架构类型

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

    (2) 基于服务的出理 方案SOA,公开应用应用线程池池业务功能的服务层,服务层在业务层之上。

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

    (4) 微服务架构

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

功能

SOA

微服务

组件大小

大块业务逻辑

单独任务或小块业务逻辑

耦合

通常松耦合

无缘无故松耦合

公司架构

任何类型

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

管理

着重中央管理

着重分散管理

目标

确保应用可不后能 交互操作

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

.Web分层设计步骤

  1.分层策略

    (1)分层粒度是选则分层策略的关键第一步.

    (2)在逻辑分层中, 多层是在同一应用应用线程池池中运行,这可不后能 利用更高性能的通信机制。这类通过组件接口直接调用。时需小心保持层之间的封装和松散耦合。

    (3)在物理分层中,选则为宜的通信机制,该机制考虑到通信延迟并保持之间的松散耦合。

    (4)多层中,考虑它们之间怎样才能相互影响,将确保性能和灵活性之间的良好平衡。

  2.选则时需层

    最常用的土办法是将表现层,服务层,业务层和数据访问层功能分离到单独的层中。一些应用应用线程池池还引入了各种组件像缓存、日志、消息队列等。

  3.决定怎样才能分发各层和组件

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

  4.选则否有有时需折叠层

    一般规则是您应始终将功能分组到层中。在一些情况表下,一1个层可不后能 充当代理或传递层,提供封装和松散耦合,而不提供少许功能。也不 ,通过分离该功能,您可不后能 稍后对其进行扩展,而对设计中的一些层几乎这麼影响,如:应用服务层。

  5.选则层之间引用的规则

    在分层策略时,您时需定义层怎样才能相互交互的规则(交互是指:各层引用的关系)。指定交互规则的主要原应是最小化依赖性并消除循环引用。也不 应该遵循以下土办法之一:

    (1)自上而下的交互

      较高级别的层可不后能 与下面的层交互,也不 较低级别的层不应该与里面的层交互。此规则将帮助您出理 层之间的循环依赖关系,以及要降低层之间的依赖性。

    (2)严格的互动

      每个层时需仅与下面的层进行交互。此规则将强制严格分离关注点,其中每个层仅知道下面的层。此规则的好处是对层界面的修改只会影响里面的层。机会您正在设计一1个将随着时间的推移进行修改以引入新功能也不 您希望最大限度地减少哪几种更改的影响的应用应用线程池池,机会您正在设计机会分布在不同物理层上的应用应用线程池池,请考虑使用此土办法。

    (3)松散的互动

      较高级别的层可不后能 绕过层直接与较低级别的层交互。这可不后能 提高性能,但也会增加依赖性换句话说,对较低级别层的修改可不后能 影响里面的多个层

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

  6.选则跨领域大问提

    定义层后,时需标识跨越层的功能。此功能通常被描述为横切关注点,包括日志记录,缓存,验证,身份验证和异常管理。选则应用应用线程池池中的每个横切关注点非常重要,并设计单独的组件以尽机会地管理哪几种大问提。此土办法可帮助您实现更好的可重用性和可维护性。

    如下图所示:NLog与Redis是具体实现组件,实现了Common层中的日志和缓存接口,Common层也不 横切组件,是跨层可重用的。像Ioc也是横切组件。 下图层的名称这麼标识跨越层的功能,机会是GFNetCore.Infra.CrossCutting.IoC 那我命名会更好。

  7.定义层之间的接口

    为层定义接口时,主要目标是强制层之间的松散耦合。这原应分析层不应暴露另一层机会依赖的內部细节。相反,层的接口应设计为通过提供隐藏层内组件细节的公共接口来最小化依赖性。你这个 隐藏称为抽象,有一些不同的土办法来实现它。以下设计土办法可用于定义层的接口:

    (1)抽象接口

      通过定义抽象基类或接口类来实现,该类充当具体类的类型定义。该类型定义了一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)。

 参考资料

   分层应用应用线程池池指南