|
|
@@ -2,6 +2,8 @@ |
|
|
|
|
|
|
|
目前攻击分配服务节点如下所示: |
|
|
|
|
|
|
|
*完整PDF文件在BPA.Documents项目中* |
|
|
|
|
|
|
|
![1650519784463](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1650519784463.png) |
|
|
|
|
|
|
|
## **其中包括(地址可直接克隆):** |
|
|
@@ -31,5 +33,177 @@ |
|
|
|
|
|
|
|
创建与开发文档相关的仓库:http://10.2.1.24:10244/Bpa.Software.Development/BPA.Documents |
|
|
|
|
|
|
|
**服务拆分需要由原有业务设计的编码人员进行拆分,在保证业务分离、不过分拆分的前提下,将代码和业务剥离到其他新的服务中** |
|
|
|
|
|
|
|
# 新框架使用介绍 |
|
|
|
|
|
|
|
原有框架使用Furion做应用程序框架,简单、易用,对于小型快速建站,它绝对是非常优秀的AppFramework,但同样也由于过度封装,导致耦合过高,拆分困难,灵活性低,不适用于企业级服务中,可查看BPA.Documents中的“问题.docx”描述。 |
|
|
|
|
|
|
|
## 层次架构 |
|
|
|
|
|
|
|
#### 1.WebApi |
|
|
|
|
|
|
|
只定义接口的对外暴露。 |
|
|
|
|
|
|
|
#### 2.Service |
|
|
|
|
|
|
|
定义和实现该服务节点下的【业务接口和业务实现】,包括IService和Service两个项目。 |
|
|
|
|
|
|
|
#### 3.Repository |
|
|
|
|
|
|
|
定义和实现该服务节点下的【仓储接口和持久化实现】,包括IRepository和Repository两个项目。 |
|
|
|
|
|
|
|
#### 4.Model |
|
|
|
|
|
|
|
实体定义和映射,包括DTO,Entity,Model。 |
|
|
|
|
|
|
|
#### 5.Bootstrap |
|
|
|
|
|
|
|
定义和配置该服务节点的所有组件,无业务实现。 |
|
|
|
|
|
|
|
#### 6.SDK |
|
|
|
|
|
|
|
定义和配置该服务节点对内需要暴露的接口,无业务实现。 |
|
|
|
|
|
|
|
#### 7.Tester |
|
|
|
|
|
|
|
该服务节点的所有接口的单元测试。 |
|
|
|
|
|
|
|
## 使用重点 |
|
|
|
|
|
|
|
##### 1、所有Service中需引用的对象,全部采用构造函数注入方式(需要什么,注入什么),禁止在业务代码中实例化一个新对象,让系统自动管理对象生成和释放。 |
|
|
|
|
|
|
|
```c# |
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor; |
|
|
|
private readonly IAuthRepository _authRepository; |
|
|
|
private readonly CSRedisClient _redisClient; |
|
|
|
private readonly BasicApiConfig _basicApiConfig; |
|
|
|
/// <summary> |
|
|
|
/// 构造函数 |
|
|
|
/// </summary> |
|
|
|
public AuthService(IHttpContextAccessor httpContextAccessor, IAuthRepository authRepository, CSRedisClient redisClient, BasicApiConfig basicApiConfig) |
|
|
|
{ |
|
|
|
_httpContextAccessor = httpContextAccessor; |
|
|
|
_authRepository = authRepository; |
|
|
|
_redisClient = redisClient; |
|
|
|
_basicApiConfig = basicApiConfig; |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
##### 2、业务面向接口编程。所有业务代码均采用interface+implement的方式进行编码,禁止直接编写implement业务实现代码。 |
|
|
|
|
|
|
|
```c# |
|
|
|
public interface IAuthService |
|
|
|
{ |
|
|
|
/// <summary> |
|
|
|
/// 获取用户 |
|
|
|
/// </summary> |
|
|
|
/// <param name="logintype"></param> |
|
|
|
/// <returns></returns> |
|
|
|
Task<BaseResult<LoginOutput>> GetLoginUserAsync(EnumLoginType logintype); |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 登录 |
|
|
|
/// </summary> |
|
|
|
/// <param name="logintype"></param> |
|
|
|
/// <param name="input"></param> |
|
|
|
/// <returns></returns> |
|
|
|
Task<BaseResult<LoginOutInfo>> LoginAsync(EnumLoginType logintype, LoginInput input); |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 登出 |
|
|
|
/// </summary> |
|
|
|
/// <returns></returns> |
|
|
|
Task<BaseResult<string>> LogoutAsync(); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
##### 3、仓储面向接口编程。所有仓储代码均采用interface+implement的方式进行编码,禁止直接编写implement仓储实现代码。 |
|
|
|
|
|
|
|
```c# |
|
|
|
public interface IAuthRepository |
|
|
|
{ |
|
|
|
/// <summary> |
|
|
|
/// 获取登录用户信息 |
|
|
|
/// </summary> |
|
|
|
/// <param name="userId"></param> |
|
|
|
/// <returns></returns> |
|
|
|
Task<BPA_Users> GetLoginUserAsync(string userId); |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 查询登录登录 |
|
|
|
/// </summary> |
|
|
|
/// <param name="LoginType"></param> |
|
|
|
/// <param name="input"></param> |
|
|
|
/// <returns></returns> |
|
|
|
Task<(BPA_Users user, BPA_Company company)> LoginAsync(EnumLoginType LoginType, LoginInput input); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
##### 4、Entity只能应用在Service和Repository层中,不能直接从API接口返回,需通过DTO进行转换。已内置DTO转换方法,MapTo和MapToList可直接无差别调用,减少冗余代码。 |
|
|
|
|
|
|
|
```c# |
|
|
|
var result = rows.MapToList<ProductCodeDto, BPA_ProductCode>().ToList(); |
|
|
|
``` |
|
|
|
|
|
|
|
##### 5、Apollo配置使用优化,在每个服务节点下均会存在一个[serviceName]ApiConfig.cs的类文件,该文件可自动映射本地成员与Apollo中的成员,使用时只需要将该对象注入,并通过对象.属性的方式获取各配置项访问,而无需使用GetSection("完全限定名")的方式访问(同样也禁止使用‘完全限定名’的方式访问)。 |
|
|
|
|
|
|
|
```c# |
|
|
|
/// <summary> |
|
|
|
/// StockMySqlDb |
|
|
|
/// </summary> |
|
|
|
[AutoWrite] |
|
|
|
public new DbConfig StockMySqlDb { get; set; } |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// RedisConfig |
|
|
|
/// </summary> |
|
|
|
[AutoWrite] |
|
|
|
public new List<string> RedisConfig { set; get; } |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 是否打印SQL |
|
|
|
/// </summary> |
|
|
|
[AutoWrite] |
|
|
|
public bool IsLogSql { get; set; } = true; |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// RabbitMQ配置 |
|
|
|
/// </summary> |
|
|
|
[AutoWrite] |
|
|
|
public new RabbitMqConnectionConfig RabbitMqConfig { get; set; } |
|
|
|
``` |
|
|
|
|
|
|
|
##### 6、已增加RabbitMQ消息队列,并在各服务节点中注入到容器,可根据实际业务进行解耦或业务编码。 |
|
|
|
|
|
|
|
```c# |
|
|
|
//获取rabbitMqProvider |
|
|
|
var rabbitMqProvider = serviceProvider.UseRabbitMQProvider<RabbitMQProvider>(); |
|
|
|
|
|
|
|
//创建交换机配置对象 |
|
|
|
var createBizLogExchangeConfig = rabbitMqProvider.BuildExchangeConfig(MqNameConfig.CreateBizLogExchange); |
|
|
|
//启用交换机 |
|
|
|
createBizLogExchangeConfig.UseExchange(); |
|
|
|
//启用生产者 |
|
|
|
createBizLogExchangeConfig.UseProducer<CreateBizLogMsgBody, CreateBizLogProducer>(); |
|
|
|
|
|
|
|
//创建交换机配置对象 |
|
|
|
var addMessageExchangeConfig = rabbitMqProvider.BuildExchangeConfig(MqNameConfig.BatchAddMessageExchange, ExchangeType.Fanout); |
|
|
|
//启用交换机 |
|
|
|
addMessageExchangeConfig.UseExchange(); |
|
|
|
//启用生产者 |
|
|
|
addMessageExchangeConfig.UseProducer<BatchAddMessageMsgBody, BatchAddMessageProduct>(); |
|
|
|
``` |
|
|
|
|
|
|
|
##### 7、已增加CSRedis作为Redis访问中间件,并已实现集群访问(集群配置咨询运维),原redis访问不在做任何支持。 |
|
|
|
|
|
|
|
```c# |
|
|
|
/// <summary> |
|
|
|
/// 注入redis |
|
|
|
/// </summary> |
|
|
|
/// <param name="services"></param> |
|
|
|
public static void AddRedis(this IServiceCollection services) |
|
|
|
{ |
|
|
|
services.UseRedisSingleton(sp => GetRedisSingletonConnectionString(sp.GetService<StockApiConfig>()!)); |
|
|
|
} |
|
|
|
``` |