-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
116 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
项目结构说明 | ||
分层项目说明 | ||
实体定义 | ||
组织代码 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.