项目结构:

cs
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.0" />
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.3.0" />
<PackageReference Include="OpenTelemetry" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
</ItemGroup>
</Project>
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BaseBusinessHandler.cs
*/
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Abstractions
{
/// <summary>
/// 责任链处理器抽象基类
/// 封装链路流转公共逻辑、全局异常捕获,所有业务处理器继承此类
/// </summary>
/// <typeparam name="T">当前处理器实现类型,用于ILogger泛型注入</typeparam>
public abstract class BaseBusinessHandler<T> : IBusinessHandler
{
/// <summary>日志实例</summary>
protected readonly ILogger<T> Logger;
/// <summary>下一个责任节点</summary>
private IBusinessHandler? _nextHandler;
protected BaseBusinessHandler(ILogger<T> logger)
{
Logger = logger;
}
/// <summary>指定后继处理器</summary>
public IBusinessHandler SetNext(IBusinessHandler nextHandler)
{
_nextHandler = nextHandler;
return this;
}
/// <summary>模板方法:执行当前环节,自动向下流转</summary>
public virtual async Task HandleAsync(JewelryBusinessContext context, CancellationToken cancellationToken = default)
{
try
{
await ProcessAsync(context, cancellationToken);
}
catch (Exception ex)
{
context.IsPass = false;
context.Remark += $"【{GetType().Name}】发生异常:{ex.Message};";
Logger.LogError(ex, "业务单号:{BusinessNo} 环节异常", context.BusinessNo);
}
// 校验通过并且存在下一节点,继续流转
if (context.IsPass && _nextHandler != null)
{
await _nextHandler.HandleAsync(context, cancellationToken);
}
else if (!context.IsPass)
{
Logger.LogWarning("业务单号:{BusinessNo} 在【{Step}】终止流转,备注:{Remark}",
context.BusinessNo, context.CurrentStep, context.Remark);
}
}
/// <summary>子类重写实现各自业务逻辑</summary>
protected abstract Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IBusinessHandler.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Abstractions
{
/// <summary>
/// 责任链处理器顶层接口
/// </summary>
public interface IBusinessHandler
{
/// <summary>设置下一个处理节点</summary>
IBusinessHandler SetNext(IBusinessHandler nextHandler);
/// <summary>异步执行业务处理</summary>
Task HandleAsync(JewelryBusinessContext context, CancellationToken cancellationToken = default);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryBusinessContext.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Abstractions
{
/// <summary>
/// 珠宝业务上下文
/// 在整条责任链流转的统一业务载体,线程隔离,每个任务独立实例
/// </summary>
public class JewelryBusinessContext
{
/// <summary>业务唯一单号</summary>
public string BusinessNo { get; set; } = string.Empty;
/// <summary>珠宝款式名称</summary>
public string JewelryName { get; set; } = string.Empty;
/// <summary>原料材质</summary>
public string Material { get; set; } = string.Empty;
/// <summary>当前环节是否校验通过</summary>
public bool IsPass { get; set; } = true;
/// <summary>流程异常备注</summary>
public string Remark { get; set; } = string.Empty;
/// <summary>当前执行环节名称</summary>
public string CurrentStep { get; set; } = string.Empty;
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节9:门店业务运营处理器</summary>
public class BusinessHandler : BaseBusinessHandler<BusinessHandler>
{
public BusinessHandler(ILogger<BusinessHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "门店业务运营";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】库存分配下发、门店销售台账同步完成", context.CurrentStep);
await Task.Delay(6, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : DesignDrawHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节2:款式设计绘图处理器</summary>
public class DesignDrawHandler : BaseBusinessHandler<DesignDrawHandler>
{
public DesignDrawHandler(ILogger<DesignDrawHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "款式设计绘图";
Logger.LogInformation("【{Step}】开始处理,单号:{No},款式:{Name}",
context.CurrentStep, context.BusinessNo, context.JewelryName);
if (string.IsNullOrWhiteSpace(context.JewelryName))
{
context.IsPass = false;
context.Remark += "款式名称为空,无法开展设计绘图;";
Logger.LogWarning("【{Step}】校验失败:款式名称缺失", context.CurrentStep);
return;
}
Logger.LogDebug("【{Step}】3D建模、图纸渲染、工艺参数确认完成", context.CurrentStep);
await Task.Delay(8, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : FinanceHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节7:财务对账结算处理器</summary>
public class FinanceHandler : BaseBusinessHandler<FinanceHandler>
{
public FinanceHandler(ILogger<FinanceHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "财务对账结算";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】原料成本核算、销售单据对账、发票信息登记完成", context.CurrentStep);
await Task.Delay(9, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : HrAdminHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节10:人事行政处理器</summary>
public class HrAdminHandler : BaseBusinessHandler<HrAdminHandler>
{
public HrAdminHandler(ILogger<HrAdminHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "人事行政统筹";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】生产/销售人员排班、绩效预登记完成", context.CurrentStep);
await Task.Delay(3, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ItHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节11:信息系统运维处理器</summary>
public class ItHandler : BaseBusinessHandler<ItHandler>
{
public ItHandler(ILogger<ItHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "信息系统运维";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】ERP单据同步、商品档案录入、数据归档完成", context.CurrentStep);
await Task.Delay(4, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LogisticsHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节6:物流发货处理器</summary>
public class LogisticsHandler : BaseBusinessHandler<LogisticsHandler>
{
public LogisticsHandler(ILogger<LogisticsHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "物流发货配送";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】保价物流下单、运单生成、出库交接完成", context.CurrentStep);
await Task.Delay(7, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MarketingHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节8:市场营销处理器</summary>
public class MarketingHandler : BaseBusinessHandler<MarketingHandler>
{
public MarketingHandler(ILogger<MarketingHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "市场营销推广";
Logger.LogInformation("【{Step}】开始处理,单号:{No},款式:{Name}",
context.CurrentStep, context.BusinessNo, context.JewelryName);
Logger.LogDebug("【{Step}】新品素材上架、门店陈列方案、活动政策配置完成", context.CurrentStep);
await Task.Delay(5, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MaterialPurchaseHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节1:原料采购核验处理器</summary>
public class MaterialPurchaseHandler : BaseBusinessHandler<MaterialPurchaseHandler>
{
public MaterialPurchaseHandler(ILogger<MaterialPurchaseHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "原料采购核验";
Logger.LogInformation("【{Step}】开始处理,单号:{No},材质:{Material},款式:{Name}",
context.CurrentStep, context.BusinessNo, context.Material, context.JewelryName);
if (string.IsNullOrWhiteSpace(context.Material))
{
context.IsPass = false;
context.Remark = "原料材质信息为空,采购审核失败";
Logger.LogWarning("【{Step}】校验失败:缺少材质信息", context.CurrentStep);
return;
}
Logger.LogDebug("【{Step}】原料入库质检、证书核对完成,审核通过", context.CurrentStep);
await Task.Delay(10, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : PackageHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节5:珠宝包装封装处理器</summary>
public class PackageHandler : BaseBusinessHandler<PackageHandler>
{
public PackageHandler(ILogger<PackageHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "珠宝包装封装";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
Logger.LogDebug("【{Step}】首饰入盒、防尘包装、防盗标签、礼品卡片封装完成", context.CurrentStep);
await Task.Delay(4, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ProduceHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节3:工厂生产加工处理器</summary>
public class ProduceHandler : BaseBusinessHandler<ProduceHandler>
{
public ProduceHandler(ILogger<ProduceHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "工厂生产加工";
Logger.LogInformation("【{Step}】开始处理,单号:{No},材质:{Material}",
context.CurrentStep, context.BusinessNo, context.Material);
Logger.LogDebug("【{Step}】开料、执模、镶嵌、抛光工序执行完毕", context.CurrentStep);
await Task.Delay(12, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : QualityCheckHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节4:成品质检处理器</summary>
public class QualityCheckHandler : BaseBusinessHandler<QualityCheckHandler>
{
public QualityCheckHandler(ILogger<QualityCheckHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "成品质量检测";
Logger.LogInformation("【{Step}】开始处理,单号:{No}",
context.CurrentStep, context.BusinessNo);
// 模拟随机质检失败场景,可注释关闭
Random rand = new Random(Guid.NewGuid().GetHashCode());
int randomResult = rand.Next(1, 101);
if (randomResult <= 5)
{
context.IsPass = false;
context.Remark += $"成品抽检不达标,随机质检编号{randomResult};";
Logger.LogWarning("【{Step}】质检不通过,需要返厂重修", context.CurrentStep);
return;
}
Logger.LogDebug("【{Step}】尺寸、成色、钻石牢固度检测全部合格,出具质检证书", context.CurrentStep);
await Task.Delay(6, cancellationToken);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : TrainingHandler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Chain.Handlers
{
/// <summary>环节12:员工培训处理器(责任链最后一环)</summary>
public class TrainingHandler : BaseBusinessHandler<TrainingHandler>
{
public TrainingHandler(ILogger<TrainingHandler> logger) : base(logger)
{
}
protected override async Task ProcessAsync(JewelryBusinessContext context, CancellationToken cancellationToken)
{
context.CurrentStep = "新品员工培训";
Logger.LogInformation("【{Step}】开始处理,单号:{No},款式:{Name}",
context.CurrentStep, context.BusinessNo, context.JewelryName);
Logger.LogDebug("【{Step}】产品卖点资料下发、导购培训计划创建完成;整条业务流程抵达末端", context.CurrentStep);
await Task.Delay(2, cancellationToken);
}
}
}
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : AppSettings.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Configuration
{
/// <summary>
/// 应用全局配置根模型,绑定appsettings.json
/// </summary>
public class AppSettings
{
/// <summary>应用业务配置节点</summary>
public AppConfig App { get; set; } = new AppConfig();
}
/// <summary>业务配置分组</summary>
public class AppConfig
{
/// <summary>日志相关配置</summary>
public LogConfig Log { get; set; } = new LogConfig();
/// <summary>并发控制配置</summary>
public ConcurrencyConfig Concurrency { get; set; } = new ConcurrencyConfig();
/// <summary>分布式追踪配置</summary>
public OpenTelemetryConfig OpenTelemetry { get; set; } = new OpenTelemetryConfig();
}
/// <summary>日志配置项</summary>
public class LogConfig
{
/// <summary>日志根目录相对路径</summary>
public string LogRootPath { get; set; } = "Logs";
/// <summary>日志文件夹保留天数,过期自动删除</summary>
public int RetainDays { get; set; }
/// <summary>最低日志输出级别</summary>
public string MinLevel { get; set; } = "Debug";
/// <summary>单个日志文件最大大小(MB),到达阈值自动切割</summary>
public int RollFileSizeMb { get; set; }
/// <summary>开启控制台日志输出</summary>
public bool EnableConsoleLog { get; set; }
/// <summary>开启文件日志输出</summary>
public bool EnableFileLog { get; set; }
}
/// <summary>并发限流配置</summary>
public class ConcurrencyConfig
{
/// <summary>最大允许并行执行业务流程数量</summary>
public int MaxConcurrentLimit { get; set; }
}
/// <summary>OpenTelemetry链路追踪配置</summary>
public class OpenTelemetryConfig
{
/// <summary>服务名称(监控面板识别)</summary>
public string ServiceName { get; set; } = string.Empty;
/// <summary>Jaeger上报地址</summary>
public string JaegerEndpoint { get; set; } = string.Empty;
/// <summary>启用Jaeger链路导出</summary>
public bool EnableJaegerExporter { get; set; }
/// <summary>启用Prometheus指标监控</summary>
public bool EnablePrometheus { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : AppSettingsBinderExtension.cs
*/
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Configuration
{
/// <summary>
/// 配置绑定扩展方法
/// </summary>
public static class AppSettingsBinderExtension
{
/// <summary>
/// 绑定配置文件并注册单例AppSettings
/// </summary>
public static IServiceCollection BindAppSettings(this IServiceCollection services, IConfiguration configuration)
{
var setting = new AppSettings();
configuration.Bind(setting);
services.AddSingleton(setting);
return services;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ServiceCollectionExtensions.cs
*/
using ChainofResponsibility.BackgroundServices;
using ChainofResponsibility.Chain.Abstractions;
using ChainofResponsibility.Chain.Handlers;
using ChainofResponsibility.Scheduler;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Extensions
{
/// <summary>
/// 业务模块统一注册扩展
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>批量注册所有责任链处理器</summary>
public static IServiceCollection AddJewelryChainHandlers(this IServiceCollection services)
{
services.AddSingleton<MaterialPurchaseHandler>();
services.AddSingleton<DesignDrawHandler>();
services.AddSingleton<ProduceHandler>();
services.AddSingleton<QualityCheckHandler>();
services.AddSingleton<PackageHandler>();
services.AddSingleton<LogisticsHandler>();
services.AddSingleton<FinanceHandler>();
services.AddSingleton<MarketingHandler>();
services.AddSingleton<BusinessHandler>();
services.AddSingleton<HrAdminHandler>();
services.AddSingleton<ItHandler>();
services.AddSingleton<TrainingHandler>();
return services;
}
/// <summary>注册调度器与后台服务</summary>
public static IServiceCollection AddJewelryBusinessServices(this IServiceCollection services)
{
services.AddSingleton<IProcessScheduler, JewelryProcessScheduler>();
services.AddHostedService<LogCleanBackgroundService>();
return services;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : CustomConsoleFormatter.cs
*/
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ChainofResponsibility.Logging
{
/// <summary>
/// 自定义控制台格式化器
/// 与文件日志输出格式完全统一,支持Activity分布式TraceId
/// </summary>
public sealed class CustomConsoleFormatter : ConsoleFormatter
{
/// <summary>格式化器唯一名称,用于配置引用</summary>
public const string FormatterName = "JewelryCustomConsole";
public CustomConsoleFormatter() : base(FormatterName)
{
}
/// <summary>日志格式化主入口</summary>
public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider? scopeProvider, TextWriter textWriter)
{
StringBuilder sb = new StringBuilder(512);
// 1.时间戳
sb.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
sb.Append(' ');
// 2.日志级别缩写
sb.Append(logEntry.LogLevel switch
{
LogLevel.Trace => "[TRC]",
LogLevel.Debug => "[DBG]",
LogLevel.Information => "[INF]",
LogLevel.Warning => "[WRN]",
LogLevel.Error => "[ERR]",
LogLevel.Critical => "[CRT]",
_ => "[UNK]"
});
sb.Append(' ');
// 3.托管线程编号
sb.Append($"Thread:{Environment.CurrentManagedThreadId} ");
// 4.分布式追踪编号
string traceId = Activity.Current?.TraceId.ToString() ?? "-";
sb.Append($"TraceId:{traceId} ");
// 5.日志分类名称
sb.Append($"[{logEntry.Category}] ");
// 6.业务消息
string message = logEntry.Formatter(logEntry.State, logEntry.Exception);
sb.Append(message);
// 7.异常堆栈信息
if (logEntry.Exception != null)
{
sb.AppendLine();
sb.Append(logEntry.Exception.ToString());
}
sb.AppendLine();
textWriter.Write(sb.ToString());
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : FileLoggerCustomFormatter.cs
*/
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Diagnostics;
using System.Text;
namespace ChainofResponsibility.Logging
{
/// <summary>
/// 文件日志格式化工具类
/// 提供统一的日志格式化输出模板
/// </summary>
public static class FileLoggerCustomFormatter
{
/// <summary>
/// 格式化日志条目为文本
/// </summary>
public static string FormatText(LogEntry<string> entry, Exception? exception)
{
var sb = new StringBuilder();
// 1.时间戳
sb.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
sb.Append(' ');
// 2.级别缩写
sb.Append(entry.LogLevel switch
{
LogLevel.Trace => "[TRC]",
LogLevel.Debug => "[DBG]",
LogLevel.Information => "[INF]",
LogLevel.Warning => "[WRN]",
LogLevel.Error => "[ERR]",
LogLevel.Critical => "[CRT]",
_ => "[UNK]"
});
sb.Append(' ');
// 3.线程ID
sb.Append($"Thread:{Environment.CurrentManagedThreadId} ");
// 4.分布式TraceId
string traceId = Activity.Current?.TraceId.ToString() ?? "-";
sb.Append($"TraceId:{traceId} ");
// 5.日志分类
sb.Append($"[{entry.Category}] ");
// 6.消息内容
sb.Append(entry.State);
// 7.异常堆栈
if (exception != null)
{
sb.AppendLine();
sb.Append(exception.ToString());
}
sb.AppendLine();
return sb.ToString();
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LoggingBuilderExtensions.cs
*/
using ChainofResponsibility.Configuration;
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
namespace ChainofResponsibility.Logging
{
/// <summary>
/// 日志模块DI扩展封装
/// </summary>
public static class LoggingBuilderExtensions
{
/// <summary>
/// 统一装配文件日志与控制台日志
/// </summary>
public static ILoggingBuilder AddJewelryLogging(this ILoggingBuilder builder, AppSettings settings, string logBaseDirectory)
{
builder.ClearProviders();
if (!Enum.TryParse<LogLevel>(settings.App.Log.MinLevel, out var minLogLevel))
{
minLogLevel = LogLevel.Debug;
}
builder.SetMinimumLevel(minLogLevel);
// 启用自定义控制台日志
if (settings.App.Log.EnableConsoleLog)
{
builder.AddConsole(opt =>
{
opt.FormatterName = CustomConsoleFormatter.FormatterName;
});
}
// 启用文件日志,使用 Karambolo 4.x API
if (settings.App.Log.EnableFileLog)
{
string todayDate = DateTime.Now.ToString("yyyy-MM-dd");
builder.AddFile(fileBuilder =>
{
fileBuilder.RootPath = logBaseDirectory;
fileBuilder.Files = new[]
{
new LogFileOptions
{
Path = $"{todayDate}/app-debug.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Debug },
MaxFileSize = settings.App.Log.RollFileSizeMb * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-info.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Information },
MaxFileSize = settings.App.Log.RollFileSizeMb * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-warn.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Warning },
MaxFileSize = settings.App.Log.RollFileSizeMb * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-error.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Error },
MaxFileSize = settings.App.Log.RollFileSizeMb * 1024 * 1024
}
};
});
}
return builder;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IProcessScheduler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Scheduler
{
/// <summary>
/// 业务流程调度器契约接口
/// </summary>
public interface IProcessScheduler
{
/// <summary>正常完整业务流程</summary>
Task RunFullNormalProcessAsync(CancellationToken cancellationToken = default);
/// <summary>采购环节失败测试流程</summary>
Task RunFailedPurchaseTestProcessAsync(CancellationToken cancellationToken = default);
/// <summary>并发压力测试(自带限流)</summary>
Task RunConcurrentStressTestAsync(int totalTaskCount, CancellationToken cancellationToken = default);
/// <summary>组装整条责任链,返回入口处理器</summary>
IBusinessHandler BuildCompleteChain();
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryProcessScheduler.cs
*/
using ChainofResponsibility.Chain.Abstractions;
using ChainofResponsibility.Chain.Handlers;
using ChainofResponsibility.Configuration;
using ChainofResponsibility.Tracing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ChainofResponsibility.Scheduler
{
/// <summary>
/// 珠宝业务流程调度实现
/// 责任链组装、任务调度、并发限流、链路追踪封装
/// </summary>
public class JewelryProcessScheduler : IProcessScheduler
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<JewelryProcessScheduler> _logger;
private readonly AppSettings _appSettings;
public JewelryProcessScheduler(IServiceProvider serviceProvider, ILogger<JewelryProcessScheduler> logger, AppSettings appSettings)
{
_serviceProvider = serviceProvider;
_logger = logger;
_appSettings = appSettings;
}
/// <summary>正常完整业务流程</summary>
public async Task RunFullNormalProcessAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation("====【正常案例】启动珠宝完整业务链路====");
var chainEntry = BuildCompleteChain();
using var activity = TraceConstants.ActivitySource.StartActivity("NormalBusinessProcess");
activity?.SetTag("BusinessNo", "JEW20260729001");
var ctx = new JewelryBusinessContext
{
BusinessNo = "JEW20260729001",
JewelryName = "满天星钻石手镯",
Material = "18K白金+天然钻石"
};
_logger.LogInformation("启动业务单号:{BusinessNo}", ctx.BusinessNo);
await chainEntry.HandleAsync(ctx, cancellationToken);
PrintResult(ctx);
}
/// <summary>采购失败测试链路,验证中断机制</summary>
public async Task RunFailedPurchaseTestProcessAsync(CancellationToken cancellationToken = default)
{
_logger.LogWarning("====【测试案例:采购环节失败,验证链路中断】====");
var chainEntry = BuildCompleteChain();
using var activity = TraceConstants.ActivitySource.StartActivity("FailedPurchaseProcess");
activity?.SetTag("BusinessNo", "JEW20260729-FAIL001");
var ctx = new JewelryBusinessContext
{
BusinessNo = "JEW20260729-FAIL001",
JewelryName = "古法黄金吊坠",
Material = string.Empty
};
_logger.LogInformation("启动失败测试单号:{BusinessNo}", ctx.BusinessNo);
await chainEntry.HandleAsync(ctx, cancellationToken);
PrintResult(ctx);
}
/// <summary>并发压力测试,SemaphoreSlim限流控制最大并行任务</summary>
public async Task RunConcurrentStressTestAsync(int totalTaskCount, CancellationToken cancellationToken = default)
{
int maxLimit = _appSettings.App.Concurrency.MaxConcurrentLimit;
_logger.LogInformation("====【并发压力测试】总任务数:{Total},最大并行限制:{Max}====", totalTaskCount, maxLimit);
List<Task> taskList = new List<Task>();
using SemaphoreSlim semaphore = new SemaphoreSlim(maxLimit, maxLimit);
for (int i = 1; i <= totalTaskCount; i++)
{
var taskIndex = i;
Task task = Task.Run(async () =>
{
await semaphore.WaitAsync(cancellationToken);
try
{
var entry = BuildCompleteChain();
string bizNo = $"JEW-STRESS-{taskIndex:D5}";
using var activity = TraceConstants.ActivitySource.StartActivity($"ConcurrentTask-{taskIndex}");
activity?.SetTag("BusinessNo", bizNo);
var ctx = new JewelryBusinessContext
{
BusinessNo = bizNo,
JewelryName = $"简约素圈戒指_{taskIndex}",
Material = taskIndex % 5 == 0 ? "" : "足金999"
};
_logger.LogDebug("并发任务启动,单号:{BizNo}", bizNo);
await entry.HandleAsync(ctx, cancellationToken);
if (!ctx.IsPass)
{
_logger.LogWarning("并发任务 {BizNo} 流程中断,原因:{Remark}", bizNo, ctx.Remark);
}
}
finally
{
semaphore.Release();
}
}, cancellationToken);
taskList.Add(task);
}
await Task.WhenAll(taskList);
_logger.LogInformation("====【并发压力测试全部任务执行完成】====");
}
/// <summary>组装完整责任链顺序</summary>
public IBusinessHandler BuildCompleteChain()
{
var purchase = _serviceProvider.GetRequiredService<MaterialPurchaseHandler>();
var design = _serviceProvider.GetRequiredService<DesignDrawHandler>();
var produce = _serviceProvider.GetRequiredService<ProduceHandler>();
var qc = _serviceProvider.GetRequiredService<QualityCheckHandler>();
var package = _serviceProvider.GetRequiredService<PackageHandler>();
var logistics = _serviceProvider.GetRequiredService<LogisticsHandler>();
var finance = _serviceProvider.GetRequiredService<FinanceHandler>();
var marketing = _serviceProvider.GetRequiredService<MarketingHandler>();
var business = _serviceProvider.GetRequiredService<BusinessHandler>();
var hr = _serviceProvider.GetRequiredService<HrAdminHandler>();
var it = _serviceProvider.GetRequiredService<ItHandler>();
var training = _serviceProvider.GetRequiredService<TrainingHandler>();
purchase
.SetNext(design)
.SetNext(produce)
.SetNext(qc)
.SetNext(package)
.SetNext(logistics)
.SetNext(finance)
.SetNext(marketing)
.SetNext(business)
.SetNext(hr)
.SetNext(it)
.SetNext(training);
return purchase;
}
/// <summary>统一打印执行结果</summary>
private void PrintResult(JewelryBusinessContext context)
{
if (context.IsPass)
{
_logger.LogInformation("【成功】单号 {No} 全业务链路全部顺利完成", context.BusinessNo);
}
else
{
_logger.LogError("【失败】单号 {No} 流程在【{Step}】中断,备注:{Remark}",
context.BusinessNo, context.CurrentStep, context.Remark);
}
_logger.LogInformation("--------------------------------------------\n");
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : OpenTelemetryBuilderExtensions.cs
*/
using ChainofResponsibility.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using System;
namespace ChainofResponsibility.Tracing
{
/// <summary>
/// OpenTelemetry追踪DI扩展
/// </summary>
public static class OpenTelemetryBuilderExtensions
{
/// <summary>
/// 装配分布式追踪:Jaeger链路
/// </summary>
public static IServiceCollection AddJewelryOpenTelemetry(this IServiceCollection services, AppSettings settings)
{
var otelCfg = settings.App.OpenTelemetry;
if (!otelCfg.EnableJaegerExporter)
return services;
services.AddOpenTelemetry()
.WithTracing(tracerBuilder =>
{
tracerBuilder
.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService(otelCfg.ServiceName))
.AddSource(TraceConstants.ActivitySourceName);
//Jaeger链路导出
if (otelCfg.EnableJaegerExporter)
{
tracerBuilder.AddJaegerExporter(opt =>
{
opt.Endpoint = new Uri(otelCfg.JaegerEndpoint);
});
}
});
return services;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : TraceConstants.cs
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ChainofResponsibility.Tracing
{
/// <summary>
/// 追踪静态常量
/// </summary>
public static class TraceConstants
{
/// <summary>链路追踪源名称</summary>
public const string ActivitySourceName = "JewelryBusinessChain";
/// <summary>全局追踪源实例</summary>
public static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName);
}
}
调用:
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 责任链模式 Chain of Responsibility Pattern
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/08 21:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ChainOfResponsibilityBll.cs
*/
using ChainofResponsibility.Configuration;
using ChainofResponsibility.Extensions;
using ChainofResponsibility.Logging;
using ChainofResponsibility.Scheduler;
using ChainofResponsibility.Tracing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Text;
namespace BLL
{
public class ChainOfResponsibilityBll
{
public async void Demo()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var host = Host.CreateDefaultBuilder(Array.Empty<string>())
.ConfigureServices((ctx, services) =>
{
//绑定配置文件
services.BindAppSettings(ctx.Configuration);
services.AddJewelryChainHandlers();
services.AddJewelryBusinessServices();
})
.ConfigureLogging((ctx, loggingBuilder) =>
{
var settings = ctx.Configuration.Get<AppSettings>()!;
string logPath = Path.Combine(AppContext.BaseDirectory, settings.App.Log.LogRootPath);
loggingBuilder.AddJewelryLogging(settings, logPath);
})
.ConfigureServices((ctx, services) =>
{
var settings = ctx.Configuration.Get<AppSettings>()!;
services.AddJewelryOpenTelemetry(settings);
})
.Build();
var scheduler = host.Services.GetRequiredService<IProcessScheduler>();
var logger = host.Services.GetRequiredService<ILogger<ChainOfResponsibilityBll>>();
Console.WriteLine("=====责任链模式演示启动=====\n");
logger.LogInformation("=====责任链模式演示启动=====");
#region 1. 完整正常业务流程测试
Console.WriteLine("【测试1】执行完整正常业务流程(全链路12个部门)");
Console.WriteLine("----------------------------------------");
logger.LogInformation("开始执行完整正常业务流程测试");
await scheduler.RunFullNormalProcessAsync();
Console.WriteLine("----------------------------------------\n");
#endregion
#region 2. 采购失败测试(验证链路中断)
Console.WriteLine("【测试2】执行采购失败测试(验证链路中断机制)");
Console.WriteLine("----------------------------------------");
logger.LogInformation("开始执行采购失败测试");
await scheduler.RunFailedPurchaseTestProcessAsync();
Console.WriteLine("----------------------------------------\n");
#endregion
#region 3. 并发压力测试
Console.WriteLine("【测试3】执行并发压力测试(10个并发任务)");
Console.WriteLine("----------------------------------------");
logger.LogInformation("开始执行并发压力测试,任务数:10");
await scheduler.RunConcurrentStressTestAsync(10);
Console.WriteLine("----------------------------------------\n");
#endregion
logger.LogInformation("所有测试执行完成");
Console.WriteLine("所有测试执行完成,按任意键退出");
Console.ReadKey();
await host.StopAsync();
}
}
}
输出:
