Skip to content

Commit

Permalink
update codes
Browse files Browse the repository at this point in the history
  • Loading branch information
niltor committed Dec 15, 2023
1 parent 4cae63d commit 6a8f548
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
2 changes: 1 addition & 1 deletion zh/ater.web/教程/.order
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
项目结构说明
分层项目说明
实体定义
组织代码
115 changes: 115 additions & 0 deletions zh/ater.web/教程/组织代码.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# 组织代码

模板已经提供了层级结构来帮助我们组织代码,对于单体应用来说,根据项目结构说明去组织相应的代码即可。

但是当我们有很多开发人员,并且有很多服务的时候,也许我们会感到困惑。这里给大家分享一下相应的解决方案,具体使用哪种方案由用户自己决定。

## 单体应用

模板提供的结构以及`Modules`可以非常方便的帮助开发者组织代码,并具备一定扩展性和协作开发的抗干扰(根据模块分工)。
最终都通过`Http.API`对外提供接口服务,这非常容易理解,也很容易实施。

## 多服务

首先要明确一下,这里的多服务,指的是在发布生产环境时,会有多个独立且不同的应用服务运行。

对于多个服务,或者说拆分成微服务,我们可以有不同的实施方案,这取决于您的团队!

> [!IMPORTANT]
> 对于方案的选择应该考虑开发者的开发体验,这主要体现在开发效率,易实施,小风险等方面,切勿为了实现别人口中所谓的“设计模式”而牺牲自己的精力和时间。
### 共享业务代码的多服务

这种方案非常容易实施,也非常容易理解,它的主要特点如下:

- 我需要在部署时部署多个服务,以让每个服务可以具备高可用。
- 我的服务共享业务逻辑代码,不同的服务只是开放不同的接口(Http/Grpc)。

这种方案让事情变得简单,假设我们最终要部署三个服务

- 用户接口服务:`Http.API`
- 管理员接口服务:`AdminService`
- 用户订单服务:`OrderService`

这意味着我们将有三个`WebAPI`项目,我们将在`Microservice`中创建`AdminService``OrderService`项目。

我们将有两种方式进行开发:

#### 1 共享业务代码

- 所有实体在`Entity`中定义,所有业务逻辑在`Application`中实现。
- 所有服务都引用`Application`项目,但只定义需要对外开放的接口。

这意味着,项目共享了所有的业务逻辑,业务逻辑并没有根据服务去拆分和解耦。

#### 2 使用模块来拆分业务代码

- 所有实体在`Entity`中定义
- 分别创建`UserMod`,`AdminMod`,`OrderMod`三个模块,分别实现各个模块的业务逻辑(即`Manager`)。
- `Http.API`项目引用 `UserMod`,`AdminService`引用`AdminMod`,`OrderService`引用`OrderMod`

这样可以在业务逻辑上实现拆分解耦,服务只会引用自己的业务实现。

由于每个模块,仍然需要引用`Application`项目,这意味着,如果有共用的业务,仍然可以进行复用,当然这也意味着,每个服务之间仍然不是完全独立和解耦的。

我们可以看到,通过模块的切分,我们可以比较灵活的进行业务逻辑的拆分,部署的拆分,同时还可以在一定程度上复用一些代码。这对于多数情况已经足够了。

如果您非要实施更加独立和解耦的服务,可继续阅读!

### 每个服务独立项目

在具体说明之前,我们需要考虑几个现实问题:

- 是否是多个团队实施微服务
- 是否使用多种语言实现
- 是否各个服务采用统一的通讯协议,如统一使用Grpc/Http,或通过消息队列进行服务间通讯。

这里会涉及到团队之间,服务之间的协作问题,可能会非常复杂。为了简化问题,我们给一些限定,以方便更好的讨论。

> 如果我们团队使用统一的语言和框架去实施微服务
我们将在这个提前下去讨论。然后我们仍然会面对一些问题:

- 是否一个解决方案对应一个服务
- 是否一个解决方案包含所有的服务
- 是否每个服务都有自己独立的仓库

关于这些问题,我们仍然需要假设一些情境,以便更好的进行讨论。

> - 使用一个仓库(主仓库)管理所有服务代码,如果服务有自已的仓库,则作为主仓库的子仓库进行管理。
> - 使用一个解决方案将所有项目进行管理。
对于.NET开发者,使用解决方案是一件非常自然的事情,这意味着你可以在一个IDE实例中处理多个项目。

接下来,假设我们需要按照`DDD`的微服务实践,让服务之间保持独立,我们应该如何去实施。

我们先明确几点:

- 每个服务只包含自己的实体(领域)模型
- 每个服务只包含自己的业务逻辑实现
- 每个服务只提供领域业务的接口
- 每个服务有自己单独的配置和依赖项
- 每个服务有自己的构建和部署需求

简而言之,服务之间几乎是完全独立的。互相是不能复用业务逻辑代码的,对于功能性代码可以通过类库的方式进行复用。

#### 1. 创建多个解决方案

其中一种方案就是为每个服务都新建一个模板项目,然后进行完全独立的开发。

那么应该如何联调么? 我们可以单独创建一个解决方案,向这个解决方案添加服务项目,然后使用`.NET Aspire`进行联调。

#### 2. 只使用一个解决方案

我们的模板自带了一个独立服务的示例。同时使用`Ater.Dry`也可以在现有解决方案中添加新的独立服务。

这些独立的服务,拥有自己的实体定义、数据库上下文、业务实现层以及接口层。这些分层不再以`独立项目`的形式存在,而是以`文件夹`的形式存在。
这很容易理解,因为所有的代码只在当前服务内起作用,并不需要封装成项目而被其他项目去引用。

`Ater.Dry`会自动发现解决方案下的微服务项目,并且代码生成时也可以识别微服务中的实体,并在对应的服务中进行代码生成。

## 建议

根据实际情况的不同,如果你的团队或业务需求不是要求您必须将各个服务进行拆分,并且相互独立,我们建议您使用模块的方式进行业务逻辑的拆分。

如果您必须去实现独立的服务,我们建议您使用一个解决方案包含所有服务方式来管理整个项目。
File renamed without changes.

0 comments on commit 6a8f548

Please sign in to comment.