Skip to content
Bitzsoft.Integrationsbitzsoft.integrations

Reference

命名与可见性

命名空间分层、类型可见性矩阵、DI 方法命名约定、HttpClient 命名与

Last updated

命名与可见性约定定义了连接器库的物理边界:哪些类型对消费者公开、哪些是内部实现细节、DI 扩展方法叫什么名字。这些约定保证跨域一致性,也让消费者只需学习一套规则即可理解所有 Provider。

命名空间分层

全库遵循固定的四层命名空间约定,对应三层包结构加上 DI 扩展所在的 Microsoft.Extensions.DependencyInjection

Bitzsoft.Integrations.{Domain} // ① 抽象层:接口、DTO、异常
Bitzsoft.Integrations.{Domain}.{Vendor} // ② 实现层:Options、Provider、ConfigProvider 接口
Bitzsoft.Integrations.{Domain}.{Vendor}.Internal // ③ 内部层:HttpClient、签名器、常量、Mapper
Microsoft.Extensions.DependencyInjection // ④ DI 扩展:ServiceCollectionExtensions

以 Payment.Stripe 为例:

// ① 抽象层——契约
namespace Bitzsoft.Integrations.Payment; // IPaymentProvider, PaymentResult<T>, PaymentException
// ② 实现层——配置与 Provider
namespace Bitzsoft.Integrations.Payment.Stripe; // StripeOptions, StripePaymentProvider, IStripeConfigProvider
// ③ 内部层——协议适配细节
namespace Bitzsoft.Integrations.Payment.Stripe.Internal; // StripeHttpClient, StripeSigner
// ④ DI 扩展——消费者入口
namespace Microsoft.Extensions.DependencyInjection; // StripeServiceCollectionExtensions

嵌套域的命名空间

Finance 域包含 Invoice、Tax、Payroll 三个子域,命名空间多一层:

Bitzsoft.Integrations.Finance.Invoice.Nuonuo // ② 实现层
Bitzsoft.Integrations.Finance.Invoice.Nuonuo.Internal // ③ 内部层

类型可见性矩阵

下表定义每个类型角色应有的访问修饰符。这是全库统一约定,新增 Provider 必须遵守。

类型角色可见性示例
抽象层接口publicIPaymentProvider
DTO / 请求响应模型publicPaymentOrderRequest
域异常publicPaymentException
域 Result 包装public sealedPaymentResult<T>
厂商 Optionspublic sealedStripeOptions
ConfigProvider 接口publicIStripeConfigProvider
Provider 实现public sealed + internal 构造函数StripePaymentProvider
HttpClient 封装internal sealedStripeHttpClient
签名器 / 验证器internal sealedStripeSigner
常量类internal sealedDingTalkConstants
Options 验证器internal sealedDingTalkOptionsValidator
ModelMapperinternal sealedDingTalkModelMapper
ConfigProvider 实现internal sealedStripeConfigProvider
DI 扩展类public staticStripeServiceCollectionExtensions
Provider Descriptorpublic sealedStripeProviderDescriptor

Provider 实现的特殊模式

Provider 类是 public sealed,但构造函数是 internal。这保证消费者无法 new 出实例,只能通过 DI 解析;同时实现类本身对 DI 容器可见(因为 DI 扩展方法用工厂委托构造)。

public sealed class StripePaymentProvider : IPaymentProvider
{
private readonly StripeHttpClient _httpClient;
private readonly IStripeConfigProvider _config;
// ① internal 构造函数——消费者无法直接 new,必须走 DI
internal StripePaymentProvider(
StripeHttpClient httpClient,
IStripeConfigProvider config,
ILogger<StripePaymentProvider> logger)
{
_httpClient = httpClient;
_config = config;
}
}

DI 方法命名

两种命名风格

// ① 推荐做法——Bitzsoft 前缀(Payment/Finance/FileStorage/TeamWork 等新域)
services.AddBitzsoftStripePayment(options => { ... });
services.AddBitzsoftDingTalkTeamWork(options => { ... });
services.AddBitzsoftAwsS3FileStorage(options => { ... });
// ② 历史遗留——短名(仅 Sms 域)
services.AddAliyunSms(options => { ... });
services.AddTencentSms(options => { ... });

命名公式

风格公式适用域
推荐AddBitzsoft{Vendor}{Domain}()除 Sms 外全部
遗留Add{Vendor}Sms()Sms
聚合AddBitzsoft{Domain}All()所有 .All

{Vendor} 是供应商品牌名(Stripe、DingTalk、AwsS3),{Domain} 是功能域名(Payment、TeamWork、FileStorage)。

方法重载约定

每个厂商至少提供两个重载——委托配置和 IConfiguration 绑定:

// ① 委托配置——适合代码内硬编码
public static IServiceCollection AddBitzsoftStripePayment(
this IServiceCollection services,
Action<StripeOptions> configure)
// ② IConfiguration 绑定——适合从 appsettings.json 读取
public static IServiceCollection AddBitzsoftStripePayment(
this IServiceCollection services,
IConfiguration configuration,
string sectionKey = "Stripe")

HttpClient 命名约定

命名 HttpClient 通过 nameof(ProviderClass) 生成,保证跨包唯一且可追溯:

public sealed class StripeOptions
{
// ① HttpClientName 默认值用 nameof(ProviderClass)
public string HttpClientName { get; set; } = nameof(StripePaymentProvider);
}

注册时用这个名字匹配 IHttpClientFactory.CreateClient()

services.AddHttpClient(options.HttpClientName).AddRequestLogging(options.HttpClientName);

#region 块组织

类型实现按固定顺序组织 #region 块,保证阅读体验一致。文件级也用 #region Members 包裹 using 后的内容。

Provider 类的标准块顺序

public sealed class StripePaymentProvider : IPaymentProvider
{
#region Constants // ① 协议常量:API 路径、字段名、前缀
private const string PathCheckoutSessions = "/v1/checkout/sessions";
#region Fields & Constructor // ② 私有只读字段 + internal 构造函数
private readonly StripeHttpClient _httpClient;
#region IPaymentProvider // ③ 接口实现(核心业务方法)
public async Task<PaymentResult<PaymentOrderResult>> CreateOrderAsync(...) { }
#region Helpers // ④ 私有辅助方法:状态映射、JSON 解析
private static PaymentStatus MapPaymentStatus(string? status) { }
}

常用 region 块清单

region 名称内容出现位置
Members文件级,包裹整个命名空间内容所有文件
Constantsprivate const 协议值Provider、HttpClient
ConfigurationOptions 类整体Options 文件
Properties公开属性Options、ConfigProvider
Fields & Constructor私有字段 + 构造函数Provider、HttpClient
Factory MethodsSuccess() / Fail() 工厂Result 类
Helpers私有辅助方法Provider、HttpClient
IDisposableDispose() 实现持有资源的类

Options 类的块组织

public sealed class StripeOptions
{
#region Credentials // 凭据字段
public string SecretKey { get; set; } = string.Empty;
#region Endpoints // 端点配置
public string ApiBase { get; set; } = "https://api.stripe.com";
#region Timeouts & Limits // 超时与限制
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
#region HttpClient // 客户端命名
public string HttpClientName { get; set; } = nameof(StripePaymentProvider);
}

Internal 文件夹结构

TeamWork.DingTalk/Internal/ 为最规范的参照,内部文件按职责分:

Internal/
├── DingTalkHttpClient.cs // HTTP 封装
├── DingTalkAuthHandler.cs // DelegatingHandler 令牌注入
├── DingTalkOptionsValidator.cs // 配置校验
├── DingTalkConstants.cs // 常量(可拆 partial)
├── DingTalkModelMapper.cs // DTO ↔ 厂商模型映射(可拆 partial)
└── JsonHelper.cs // JSON 辅助

相关约定

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%