CSharp:Chain of Responsibility Pattern

项目结构:

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();
        }
    }
}

输出:

相关推荐
半夜里咳嗽的狼1 小时前
Go 1.25 的 WaitGroup.Go 省了两行代码,也补不上这三个并发边界
后端·go
山峰哥1 小时前
数据库性能救星:Explain执行计划深度拆解
服务器·开发语言·数据库·sql·启发式算法
Lihua奏1 小时前
身份验证:登录之后,服务器怎么一直认得你?
后端
程序员天天困1 小时前
Arthas ognl 表达式从入门到实战:掌握在线调试最强的表达式引擎
java·jvm·后端
Escape1 小时前
为什么你的 AI 越聊越傻?从 Token 到 Agent,彻底搞懂 AI Agent的秘密㊙️
前端·人工智能·后端
用户40966601317512 小时前
Lombok 你用对了吗?@Data 之外的 6 个隐藏神器
java·后端·代码规范
董员外2 小时前
RAG 系统进化论(二):Naive RAG,检索增强生成的最小闭环
前端·人工智能·后端
花生了什么事o2 小时前
synchronized 与 ReentrantLock:Java 锁机制原理与实现对比
java·开发语言
掘金一周3 小时前
看看大家每月的成本有多少 | 沸点周刊 7.30
前端·人工智能·后端
aramae3 小时前
C++ IO流完全指南:从C标准库到C++流式编程
服务器·c语言·开发语言·c++·后端