CSharp: Strategy Pattern

项目结构:

7530fc18-05ea-4d18-970a-39e74d73e7a3

 

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : BusinessFlowRecord.cs 
 */

using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Entities
{
    /// <summary>
    /// 业务流程流转记录实体,记录每一步业务策略执行流水
    /// </summary>
    public class BusinessFlowRecord
    {
        /// <summary>
        /// 流水记录主键
        /// </summary>
        public long RecordId { get; private set; }

        /// <summary>
        /// 外部业务唯一ID
        /// </summary>
        public long BusinessId { get; private set; }

        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName { get; private set; } = string.Empty;

        /// <summary>
        /// 流程状态
        /// </summary>
        public BusinessFlowStatus FlowStatus { get; private set; }

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; private set; } = string.Empty;

        /// <summary>
        /// 错误码
        /// </summary>
        public int ErrorCode { get; private set; }

        /// <summary>
        /// 操作人信息
        /// </summary>
        public OperatorInfo Operator { get; private set; }

        /// <summary>
        /// 执行UTC时间
        /// </summary>
        public DateTime ExecuteUtcTime { get; private set; }

        private BusinessFlowRecord()
        {
        }

        /// <summary>
        /// 工厂创建流程记录
        /// </summary>
        public static BusinessFlowRecord Create(long recordId, long businessId, string phaseName,
            BusinessFlowStatus flowStatus, string message, int errorCode, OperatorInfo opInfo)
        {
            if (recordId <= 0) throw new ArgumentException("记录ID必须大于0");
            if (businessId <= 0) throw new ArgumentException("业务ID必须大于0");
            if (string.IsNullOrWhiteSpace(phaseName)) throw new ArgumentException("业务环节不能为空");

            return new BusinessFlowRecord
            {
                RecordId = recordId,
                BusinessId = businessId,
                PhaseName = phaseName,
                FlowStatus = flowStatus,
                Message = message,
                ErrorCode = errorCode,
                Operator = opInfo,
                ExecuteUtcTime = DateTime.UtcNow
            };
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryMaterial.cs 
 */
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Entities
{
    /// <summary>
    /// 珠宝原料 领域实体,拥有唯一业务标识
    /// </summary>
    public class JewelryMaterial
    {
        /// <summary>
        /// 原料唯一编号
        /// </summary>
        public long Id { get; private set; }

        /// <summary>
        /// 物料编码
        /// </summary>
        public string MaterialCode { get; private set; } = string.Empty;

        /// <summary>
        /// 原料名称
        /// </summary>
        public string MaterialName { get; private set; } = string.Empty;

        /// <summary>
        /// 重量,单位克
        /// </summary>
        public decimal WeightGram { get; private set; }

        /// <summary>
        /// 品质等级
        /// </summary>
        public MaterialQualityGrade QualityGrade { get; private set; }

        /// <summary>
        /// 采购成本金额
        /// </summary>
        public Money PurchaseCost { get; private set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; private set; }

        /// <summary>
        /// 是否已经核验通过
        /// </summary>
        public bool IsVerified { get; private set; }

        /// <summary>
        /// 私有构造,领域实体禁止外部new
        /// </summary>
        private JewelryMaterial()
        {
        }

        /// <summary>
        /// 工厂方法创建珠宝原料实体
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <param name="materialCode">物料编码</param>
        /// <param name="materialName">物料名称</param>
        /// <param name="weightGram">重量克</param>
        /// <param name="qualityGrade">品质等级</param>
        /// <param name="purchaseCost">采购成本</param>
        /// <returns>实体实例</returns>
        public static JewelryMaterial Create(long id,
            string materialCode,
            string materialName,
            decimal weightGram,
            MaterialQualityGrade qualityGrade,
            Money purchaseCost)
        {
            if (id <= 0) throw new ArgumentException("实体ID必须大于0");
            if (string.IsNullOrWhiteSpace(materialCode)) throw new ArgumentException("物料编码不能为空");
            if (string.IsNullOrWhiteSpace(materialName)) throw new ArgumentException("物料名称不能为空");
            if (weightGram <= 0) throw new ArgumentException("重量必须大于0");

            return new JewelryMaterial
            {
                Id = id,
                MaterialCode = materialCode,
                MaterialName = materialName,
                WeightGram = weightGram,
                QualityGrade = qualityGrade,
                PurchaseCost = purchaseCost,
                CreateTime = DateTime.UtcNow,
                IsVerified = false
            };
        }

        /// <summary>
        /// 标记原料核验通过,领域内业务行为
        /// </summary>
        public void MarkVerified()
        {
            IsVerified = true;
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryProduct.cs 
 */

using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Entities
{
    /// <summary>
    /// 珠宝成品产品实体
    /// </summary>
    public class JewelryProduct
    {
        /// <summary>
        /// 产品主键ID
        /// </summary>
        public long Id { get; private set; }

        /// <summary>
        /// 产品外部编号
        /// </summary>
        public string ProductNo { get; private set; } = string.Empty;

        /// <summary>
        /// 产品名称
        /// </summary>
        public string ProductName { get; private set; } = string.Empty;

        /// <summary>
        /// 对应原料ID
        /// </summary>
        public long MaterialId { get; private set; }

        /// <summary>
        /// 销售定价
        /// </summary>
        public Money SalePrice { get; private set; }

        /// <summary>
        /// 是否质检合格
        /// </summary>
        public bool IsQualityPass { get; private set; }

        /// <summary>
        /// 创建UTC时间
        /// </summary>
        public DateTime CreateUtcTime { get; private set; }

        private JewelryProduct()
        {
        }

        /// <summary>
        /// 工厂创建成品
        /// </summary>
        public static JewelryProduct Create(long id, string productNo, string productName, long materialId, Money salePrice)
        {
            if (id <= 0) throw new ArgumentException("产品ID必须大于0");
            if (string.IsNullOrWhiteSpace(productNo)) throw new ArgumentException("产品编号不能为空");
            if (string.IsNullOrWhiteSpace(productName)) throw new ArgumentException("产品名称不能为空");
            if (materialId <= 0) throw new ArgumentException("关联原料ID非法");

            return new JewelryProduct
            {
                Id = id,
                ProductNo = productNo,
                ProductName = productName,
                MaterialId = materialId,
                SalePrice = salePrice,
                IsQualityPass = false,
                CreateUtcTime = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 设置质检合格
        /// </summary>
        public void SetQualityPass()
        {
            IsQualityPass = true;
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : BusinessFlowStatus.cs 
 */
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Enums
{
    /// <summary>
    /// 业务流程执行状态枚举
    /// </summary>
    public enum BusinessFlowStatus
    {
        /// <summary>
        /// 未执行
        /// </summary>
        None = 0,
        /// <summary>
        /// 执行成功
        /// </summary>
        Success = 1,
        /// <summary>
        /// 执行失败
        /// </summary>
        Failed = 2,
        /// <summary>
        /// 熔断拦截
        /// </summary>
        CircuitBlocked = 3
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MaterialQualityGrade.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Enums
{
    /// <summary>
    /// 珠宝原料品质等级
    /// </summary>
    public enum MaterialQualityGrade
    {
        /// <summary>
        /// 未评级
        /// </summary>
        UnGrade = 0,
        /// <summary>
        /// A级优质
        /// </summary>
        GradeA = 1,
        /// <summary>
        /// B级普通
        /// </summary>
        GradeB = 2,
        /// <summary>
        /// C级次品
        /// </summary>
        GradeC = 3
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IBusinessFlowRecordRepository.cs 
 */

using StrategyPattern.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Interfaces
{
    /// <summary>
    /// 业务流程流水记录仓储接口
    /// </summary>
    public interface IBusinessFlowRecordRepository
    {
        /// <summary>
        /// 新增流程流水记录
        /// </summary>
        /// <param name="record">流水记录实体</param>
        Task AddAsync(BusinessFlowRecord record);

        /// <summary>
        /// 根据业务ID查询全部流水
        /// </summary>
        /// <param name="businessId">业务编号</param>
        /// <returns>流水集合</returns>
        Task<List<BusinessFlowRecord>> QueryByBusinessIdAsync(long businessId);
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IJewelryMaterialRepository.cs 
 */
using StrategyPattern.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Interfaces
{
    /// <summary>
    /// 珠宝原料仓储接口,领域层只定义接口,实现在基础设施层
    /// </summary>
    public interface IJewelryMaterialRepository
    {
        /// <summary>
        /// 根据ID获取原料
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>原料实体,没有返回null</returns>
        Task<JewelryMaterial?> GetByIdAsync(long id);

        /// <summary>
        /// 根据物料编码查询
        /// </summary>
        /// <param name="materialCode">物料编码</param>
        /// <returns>实体</returns>
        Task<JewelryMaterial?> GetByCodeAsync(string materialCode);

        /// <summary>
        /// 添加原料
        /// </summary>
        /// <param name="entity">原料实体</param>
        Task AddAsync(JewelryMaterial entity);

        /// <summary>
        /// 更新原料
        /// </summary>
        /// <param name="entity">原料实体</param>
        Task UpdateAsync(JewelryMaterial entity);
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IUnitOfWork.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Interfaces
{
    /// <summary>
    /// 工作单元接口,控制事务,领域层抽象
    /// </summary>
    public interface IUnitOfWork
    {
        /// <summary>
        /// 提交全部变更
        /// </summary>
        /// <returns>受影响行数</returns>
        Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MaterialDomainService.cs 
 */

using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.Services
{
    /// <summary>
    /// 原料领域服务,处理领域业务规则,不依赖外部基础设施
    /// </summary>
    public class MaterialDomainService
    {
        private readonly IJewelryMaterialRepository _materialRepo;

        /// <summary>
        /// 构造注入仓储接口
        /// </summary>
        /// <param name="materialRepo">原料仓储接口</param>
        public MaterialDomainService(IJewelryMaterialRepository materialRepo)
        {
            _materialRepo = materialRepo;
        }

        /// <summary>
        /// 执行原料核验领域规则校验
        /// </summary>
        /// <param name="materialCode">物料编码</param>
        /// <param name="opInfo">操作人员</param>
        /// <returns>核验后的原料实体</returns>
        /// <exception cref="InvalidOperationException">校验不通过抛出领域异常</exception>
        public async Task<JewelryMaterial> VerifyMaterialAsync(string materialCode, OperatorInfo opInfo)
        {
            var material = await _materialRepo.GetByCodeAsync(materialCode);
            if (material is null)
            {
                throw new InvalidOperationException($"物料编码[{materialCode}]不存在");
            }
            if (material.IsVerified)
            {
                throw new InvalidOperationException($"物料[{materialCode}]已经完成核验,不可重复核验");
            }
            //领域业务规则:重量必须大于0
            if (material.WeightGram <= 0)
            {
                throw new InvalidOperationException($"物料[{materialCode}]重量非法,无法核验");
            }
            material.MarkVerified();
            await _materialRepo.UpdateAsync(material);
            return material;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : Money.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.ValueObjects
{
    /// <summary>
    /// 金额值对象,封装货币,防止浮点数精度问题
    /// </summary>
    public record Money
    {
        /// <summary>
        /// 金额数值
        /// </summary>
        public decimal Amount { get; }

        /// <summary>
        /// 货币单位
        /// </summary>
        public string Currency { get; }

        /// <summary>
        /// 私有构造
        /// </summary>
        /// <param name="amount">金额</param>
        /// <param name="currency">货币</param>
        private Money(decimal amount, string currency)
        {
            Amount = amount;
            Currency = currency;
        }

        /// <summary>
        /// 创建人民币金额
        /// </summary>
        /// <param name="amount">金额</param>
        /// <returns>Money实例</returns>
        public static Money CreateCny(decimal amount)
        {
            if (amount < 0)
                throw new ArgumentException("金额不能为负数");
            return new Money(amount, "CNY");
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : OperatorInfo.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Domain.ValueObjects
{
    /// <summary>
    /// 操作人员信息 值对象,无独立ID,不可变
    /// </summary>
    public record OperatorInfo
    {
        /// <summary>
        /// 操作人员编号
        /// </summary>
        public long OperatorId { get; }

        /// <summary>
        /// 操作人员姓名
        /// </summary>
        public string OperatorName { get; }

        /// <summary>
        /// 所属部门
        /// </summary>
        public string Department { get; }

        /// <summary>
        /// 私有构造,只能通过工厂方法创建
        /// </summary>
        /// <param name="operatorId">操作员ID</param>
        /// <param name="operatorName">操作员名称</param>
        /// <param name="department">部门名称</param>
        private OperatorInfo(long operatorId, string operatorName, string department)
        {
            OperatorId = operatorId;
            OperatorName = operatorName;
            Department = department;
        }

        /// <summary>
        /// 工厂方法创建操作人员信息
        /// </summary>
        /// <param name="operatorId">操作员ID</param>
        /// <param name="operatorName">操作员名称</param>
        /// <param name="department">部门名称</param>
        /// <returns>值对象实例</returns>
        /// <exception cref="ArgumentException">参数校验异常</exception>
        public static OperatorInfo Create(long operatorId, string operatorName, string department)
        {
            if (operatorId <= 0)
                throw new ArgumentException("操作员ID必须大于0");
            if (string.IsNullOrWhiteSpace(operatorName))
                throw new ArgumentException("操作员名称不能为空");
            if (string.IsNullOrWhiteSpace(department))
                throw new ArgumentException("部门不能为空");

            return new OperatorInfo(operatorId, operatorName, department);
        }
    }
}

  

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : BusinessExecuteResultDto.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Dtos
{
    /// <summary>
    /// 业务策略执行返回结果DTO
    /// </summary>
    public class BusinessExecuteResultDto
    {
        /// <summary>
        /// 是否执行成功
        /// </summary>
        public bool IsSuccess { get; set; }

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; } = string.Empty;

        /// <summary>
        /// 业务输出数据对象
        /// </summary>
        public object? OutputData { get; set; }

        /// <summary>
        /// 业务错误码,0代表无错误
        /// </summary>
        public int ErrorCode { get; set; }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryBusinessInputDto.cs 
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Dtos
{
    /// <summary>
    /// 珠宝业务输入DTO,应用层接收外部输入数据
    /// </summary>
    public class JewelryBusinessInputDto
    {
        /// <summary>
        /// 业务唯一编号
        /// </summary>
        public long BusinessId { get; set; }

        /// <summary>
        /// 当前业务环节名称
        /// </summary>
        public string BusinessPhase { get; set; } = string.Empty;

        /// <summary>
        /// 原料物料编码
        /// </summary>
        public string MaterialCode { get; set; } = string.Empty;

        /// <summary>
        /// 珠宝产品编号
        /// </summary>
        public string ProductNo { get; set; } = string.Empty;

        /// <summary>
        /// 业务数量
        /// </summary>
        public decimal Quantity { get; set; }

        /// <summary>
        /// 业务金额
        /// </summary>
        public decimal Amount { get; set; }

        /// <summary>
        /// 操作人员ID
        /// </summary>
        public long OperatorId { get; set; }

        /// <summary>
        /// 操作人员名称
        /// </summary>
        public string OperatorName { get; set; } = string.Empty;

        /// <summary>
        /// 操作人员所属部门
        /// </summary>
        public string OperatorDepartment { get; set; } = string.Empty;

        /// <summary>
        /// 业务备注
        /// </summary>
        public string Remark { get; set; } = string.Empty;

        /// <summary>
        /// 业务发生本地时间
        /// </summary>
        public DateTime OccurTime { get; set; }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IBusinessStrategy.cs 
 */

using StrategyPattern.Application.Dtos;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Interfaces
{
    /// <summary>
    /// 业务策略接口,策略模式抽象,应用层定义
    /// 每一个珠宝业务环节实现该接口,实现开闭原则
    /// </summary>
    public interface IBusinessStrategy
    {
        /// <summary>
        /// 获取业务环节显示名称
        /// </summary>
        string PhaseName { get; }

        /// <summary>
        /// 执行业务逻辑
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>业务执行结果DTO</returns>
        Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input);
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IResilienceExecutor.cs 
 */
using StrategyPattern.Application.Dtos;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Interfaces
{
    /// <summary>
    /// 弹性执行器接口:重试+熔断,应用层抽象,实现在基础设施层
    /// </summary>
    public interface IResilienceExecutor
    {
        /// <summary>
        /// 使用熔断重试包装业务委托执行
        /// </summary>
        /// <param name="businessFunc">业务异步委托</param>
        /// <param name="businessId">业务编号,用于日志追踪</param>
        /// <returns>业务执行结果</returns>
        Task<BusinessExecuteResultDto> ExecuteWithResilienceAsync(Func<Task<BusinessExecuteResultDto>> businessFunc, long businessId);
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : BusinessStrategyContext.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Services
{
    /// <summary>
    /// 策略上下文,持有策略实例,对外统一调用入口
    /// 职责:封装策略切换,调用策略执行,记录日志
    /// </summary>
    public class BusinessStrategyContext
    {
        private readonly ILogger<BusinessStrategyContext> _logger;
        private IBusinessStrategy? _currentStrategy;

        /// <summary>
        /// 构造注入日志对象
        /// </summary>
        /// <param name="logger">日志实例</param>
        public BusinessStrategyContext(ILogger<BusinessStrategyContext> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 设置当前运行的业务策略
        /// </summary>
        /// <param name="strategy">业务策略实现</param>
        public void SetStrategy(IBusinessStrategy strategy)
        {
            _logger.LogDebug("业务策略切换,目标环节:{PhaseName}", strategy.PhaseName);
            _currentStrategy = strategy;
        }

        /// <summary>
        /// 异步执行当前策略业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        /// <exception cref="InvalidOperationException">策略未设置抛出异常</exception>
        public async Task<BusinessExecuteResultDto> RunAsync(JewelryBusinessInputDto input)
        {
            if (_currentStrategy is null)
            {
                _logger.LogError("BusinessStrategyContext未设置业务策略,BusinessId:{BusinessId}", input.BusinessId);
                throw new InvalidOperationException("未指定业务处理策略实例");
            }

            _logger.LogInformation("开始执行业务环节:{PhaseName} BusinessId:{BusinessId}",
                _currentStrategy.PhaseName, input.BusinessId);

            var result = await _currentStrategy.ExecuteAsync(input);

            if (result.IsSuccess)
            {
                _logger.LogInformation("业务环节执行成功 {PhaseName} BusinessId:{BusinessId} Msg:{Msg}",
                    _currentStrategy.PhaseName, input.BusinessId, result.Message);
            }
            else
            {
                _logger.LogWarning("业务环节执行失败 {PhaseName} BusinessId:{BusinessId} Code:{Code} Msg:{Msg}",
                    _currentStrategy.PhaseName, input.BusinessId, result.ErrorCode, result.Message);
            }
            return result;
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryFlowApplicationService.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Services
{
/// <summary>
/// 珠宝业务流程应用服务,编排完整业务流水线,应用层协调领域、策略、弹性组件
/// 职责单一:只做业务编排,不写具体业务逻辑,业务逻辑下沉到各个Strategy
/// </summary>
public class JewelryFlowApplicationService
    {
        private readonly ILogger<JewelryFlowApplicationService> _logger;
        private readonly BusinessStrategyContext _strategyContext;
        private readonly IResilienceExecutor _resilienceExecutor;
        private readonly IEnumerable<IBusinessStrategy> _allBusinessStrategies;
        private readonly IBusinessFlowRecordRepository _flowRecordRepo;
        private readonly IUnitOfWork _unitOfWork;

        /// <summary>
        /// DI构造注入全部依赖
        /// </summary>
        /// <param name="logger">日志</param>
        /// <param name="strategyContext">策略上下文</param>
        /// <param name="resilienceExecutor">弹性熔断重试执行器</param>
        /// <param name="allBusinessStrategies">全部业务策略集合</param>
        /// <param name="flowRecordRepo">流程流水仓储</param>
        /// <param name="unitOfWork">工作单元</param>
        public JewelryFlowApplicationService(
            ILogger<JewelryFlowApplicationService> logger,
            BusinessStrategyContext strategyContext,
            IResilienceExecutor resilienceExecutor,
            IEnumerable<IBusinessStrategy> allBusinessStrategies,
            IBusinessFlowRecordRepository flowRecordRepo,
            IUnitOfWork unitOfWork)
        {
            _logger = logger;
            _strategyContext = strategyContext;
            _resilienceExecutor = resilienceExecutor;
            _allBusinessStrategies = allBusinessStrategies;
            _flowRecordRepo = flowRecordRepo;
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 根据环节名称获取对应策略实例
        /// </summary>
        /// <param name="phaseName">业务环节名称</param>
        /// <returns>业务策略实例</returns>
        /// <exception cref="NotSupportedException">找不到策略抛出异常</exception>
        private IBusinessStrategy GetStrategyByPhaseName(string phaseName)
        {
            var strategy = _allBusinessStrategies.FirstOrDefault(s => s.PhaseName == phaseName);
            if (strategy == null)
            {
                _logger.LogError("无法找到业务策略,环节名称:{PhaseName}", phaseName);
                throw new NotSupportedException($"不支持的业务环节:{phaseName}");
            }
            return strategy;
        }

        /// <summary>
        /// 保存流程执行流水记录
        /// </summary>
        /// <param name="input">输入DTO</param>
        /// <param name="result">执行结果</param>
        private async Task SaveFlowRecordAsync(JewelryBusinessInputDto input, BusinessExecuteResultDto result)
        {
            var opInfo = OperatorInfo.Create(input.OperatorId, input.OperatorName, input.OperatorDepartment);
            var flowStatus = result.IsSuccess ? BusinessFlowStatus.Success : BusinessFlowStatus.Failed;
            long recordId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            var record = BusinessFlowRecord.Create(
                recordId: recordId,
                businessId: input.BusinessId,
                phaseName: input.BusinessPhase,
                flowStatus: flowStatus,
                message: result.Message,
                errorCode: result.ErrorCode,
                opInfo: opInfo);

            await _flowRecordRepo.AddAsync(record);
            await _unitOfWork.SaveChangesAsync();
        }

        /// <summary>
        /// 执行单个业务环节(外层包装熔断重试)
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>业务执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteSinglePhaseAsync(JewelryBusinessInputDto input)
        {
            _logger.LogInformation("应用服务开始调度单环节 BusinessId:{BusinessId} Phase:{Phase}",
                input.BusinessId, input.BusinessPhase);

            var strategy = GetStrategyByPhaseName(input.BusinessPhase);
            _strategyContext.SetStrategy(strategy);

            //使用弹性适配器包装策略执行
            var result = await _resilienceExecutor.ExecuteWithResilienceAsync(async () =>
            {
                return await _strategyContext.RunAsync(input);
            }, input.BusinessId);

            //写入流程流水记录
            await SaveFlowRecordAsync(input, result);

            _logger.LogInformation("应用服务单环节执行完成 BusinessId:{BusinessId} Success:{Success}",
                input.BusinessId, result.IsSuccess);
            return result;
        }

        /// <summary>
        /// 执行珠宝完整业务流水线:原料采购核验→设计制图→加工生产→质检→包装→物流→财务
        /// </summary>
        /// <param name="baseInput">基础业务输入DTO</param>
        /// <returns>每一步骤执行结果集合</returns>
        public async Task<List<BusinessExecuteResultDto>> ExecuteFullJewelryPipelineAsync(JewelryBusinessInputDto baseInput)
        {
            _logger.LogInformation("==========启动珠宝完整业务流水线 BusinessId:{BusinessId} ==========", baseInput.BusinessId);

            List<string> pipelinePhaseList = new List<string>
        {
            "原料采购核验",
            "设计制图",
            "加工生产",
            "质检",
            "包装",
            "物流",
            "财务"
        };

            var resultCollection = new List<BusinessExecuteResultDto>();

            foreach (var phaseName in pipelinePhaseList)
            {
                var phaseInputDto = new JewelryBusinessInputDto
                {
                    BusinessId = baseInput.BusinessId,
                    BusinessPhase = phaseName,
                    MaterialCode = baseInput.MaterialCode,
                    ProductNo = baseInput.ProductNo,
                    Quantity = baseInput.Quantity,
                    Amount = baseInput.Amount,
                    OperatorId = baseInput.OperatorId,
                    OperatorName = baseInput.OperatorName,                  
                    OperatorDepartment = baseInput.OperatorDepartment,
                    Remark = baseInput.Remark,
                    OccurTime = DateTime.UtcNow
                };

                var phaseResult = await ExecuteSinglePhaseAsync(phaseInputDto);
                resultCollection.Add(phaseResult);

                // 如果某一步失败,终止流水线
                if (!phaseResult.IsSuccess)
                {
                    _logger.LogError("业务流水线在环节【{PhaseName}】中断,BusinessId:{BusinessId}", phaseName, baseInput.BusinessId);
                    break;
                }
            }

            _logger.LogInformation("==========珠宝完整业务流水线执行结束 BusinessId:{BusinessId} ==========", baseInput.BusinessId);
            return resultCollection;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : DesignDrawStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:设计制图业务环节
    /// </summary>
    public class DesignDrawStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "设计制图";

        private readonly ILogger<DesignDrawStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public DesignDrawStrategy(ILogger<DesignDrawStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行业务逻辑
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("设计制图环节开始执行 BusinessId:{BusinessId}", input.BusinessId);

                if (input.Quantity <= 0)
                {
                    return new BusinessExecuteResultDto
                    {
                        IsSuccess = false,
                        ErrorCode = 2001,
                        Message = "设计数量必须大于0"
                    };
                }

                //模拟3D制图耗时
                await Task.Delay(10);

                var designOutput = new
                {
                    BusinessId = input.BusinessId,
                    ProductNo = input.ProductNo,
                    DesignFileId = $"DES-{input.BusinessId}",
                    Designer = input.OperatorName,
                    CreateUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"3D设计制图完成,产品编号:{input.ProductNo}",
                    OutputData = designOutput
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设计制图环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"设计制图异常:{ex.Message}"
                };
            }
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : FinanceSettleStrategy.cs 
 */
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:财务结算业务环节
    /// </summary>
    public class FinanceSettleStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "财务";

        private readonly ILogger<FinanceSettleStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public FinanceSettleStrategy(ILogger<FinanceSettleStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行财务结算业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("财务结算环节开始执行 BusinessId:{BusinessId}", input.BusinessId);

                if (input.Amount <= 0)
                {
                    return new BusinessExecuteResultDto
                    {
                        IsSuccess = false,
                        ErrorCode = 7001,
                        Message = "结算金额必须大于0"
                    };
                }

                await Task.Delay(10);

                var financeData = new
                {
                    BusinessId = input.BusinessId,
                    BillNo = $"BILL-{input.BusinessId}",
                    SettleAmount = input.Amount,
                    FinanceOperator = input.OperatorName,
                    SettleUtcTime = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"财务结算完成,单据号:{financeData.BillNo},结算金额:{input.Amount}",
                    OutputData = financeData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "财务结算环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"财务结算异常:{ex.Message}"
                };
            }
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : HumanResourceStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:人事业务环节(支持部门)
    /// </summary>
    public class HumanResourceStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "人事";

        private readonly ILogger<HumanResourceStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public HumanResourceStrategy(ILogger<HumanResourceStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行人事业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("人事业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(5);

                var hrOutput = new
                {
                    BusinessId = input.BusinessId,
                    OperatorDept = input.OperatorDepartment,
                    OperateUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"人事业务处理完成,操作部门:{input.OperatorDepartment}",
                    OutputData = hrOutput
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "人事环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"人事业务异常:{ex.Message}"
                };
            }
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : LogisticsStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:物流业务环节
    /// </summary>
    public class LogisticsStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "物流";

        private readonly ILogger<LogisticsStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public LogisticsStrategy(ILogger<LogisticsStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行物流业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("物流环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(12);

                var logisticsData = new
                {
                    ProductNo = input.ProductNo,
                    ExpressNo = $"EXP-{input.BusinessId}",
                    ShipOperator = input.OperatorName,
                    ShipUtcTime = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"物流发货完成,快递单号:{logisticsData.ExpressNo}",
                    OutputData = logisticsData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "物流环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"物流异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : ManufactureProduceStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:加工生产业务环节
    /// </summary>
    public class ManufactureProduceStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "加工生产";

        private readonly ILogger<ManufactureProduceStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public ManufactureProduceStrategy(ILogger<ManufactureProduceStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行加工生产业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("加工生产环节开始执行 BusinessId:{BusinessId}", input.BusinessId);

                if (string.IsNullOrWhiteSpace(input.ProductNo))
                {
                    return new BusinessExecuteResultDto
                    {
                        IsSuccess = false,
                        ErrorCode = 3001,
                        Message = "产品编号不能为空,无法开始加工"
                    };
                }

                await Task.Delay(15);

                var manufactureResult = new
                {
                    ProductNo = input.ProductNo,
                    ProcessBatchNo = $"BATCH-{input.BusinessId}",
                    ProduceCount = input.Quantity,
                    ProduceTimeUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"加工生产完成,批次号:{manufactureResult.ProcessBatchNo}",
                    OutputData = manufactureResult
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加工生产环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"加工生产异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MarketingStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:营销业务环节
    /// </summary>
    public class MarketingStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "营销";

        private readonly ILogger<MarketingStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public MarketingStrategy(ILogger<MarketingStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行营销业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("营销业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(8);

                var marketingOutput = new
                {
                    BusinessId = input.BusinessId,
                    ProductNo = input.ProductNo,
                    MarketAmount = input.Amount,
                    MarketUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"营销业务处理完成,产品:{input.ProductNo}",
                    OutputData = marketingOutput
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "营销环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"营销业务异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MaterialPurchaseVerifyStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Domain.Services;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:原料采购核验环节
    /// </summary>
    public class MaterialPurchaseVerifyStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "原料采购核验";

        private readonly ILogger<MaterialPurchaseVerifyStrategy> _logger;
        private readonly MaterialDomainService _materialDomainService;

        /// <summary>
        /// 构造注入
        /// </summary>
        /// <param name="logger">日志对象</param>
        /// <param name="materialDomainService">原料领域服务</param>
        public MaterialPurchaseVerifyStrategy(ILogger<MaterialPurchaseVerifyStrategy> logger, MaterialDomainService materialDomainService)
        {
            _logger = logger;
            _materialDomainService = materialDomainService;
        }

        /// <summary>
        /// 执行原料采购核验业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("原料采购核验开始,物料编码:{MaterialCode}, BusinessId:{BusinessId}", input.MaterialCode, input.BusinessId);

                if (string.IsNullOrWhiteSpace(input.MaterialCode))
                {
                    return new BusinessExecuteResultDto
                    {
                        IsSuccess = false,
                        ErrorCode = 1001,
                        Message = "物料编码不能为空"
                    };
                }

                var opInfo = OperatorInfo.Create(input.OperatorId, input.OperatorName, input.OperatorDepartment);
                var verifiedMaterial = await _materialDomainService.VerifyMaterialAsync(input.MaterialCode, opInfo);

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"原料核验成功,物料编号:{verifiedMaterial.MaterialCode},重量:{verifiedMaterial.WeightGram}g",
                    OutputData = verifiedMaterial
                };
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogWarning(ex, "原料采购核验业务校验失败 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 1002,
                    Message = ex.Message
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "原料采购核验发生未知异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"系统异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : PackageStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:包装业务环节
    /// </summary>
    public class PackageStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "包装";

        private readonly ILogger<PackageStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public PackageStrategy(ILogger<PackageStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行包装业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("包装环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(6);

                var packageData = new
                {
                    ProductNo = input.ProductNo,
                    PackageBoxNo = $"PK-{input.BusinessId}",
                    PackageOperator = input.OperatorName,
                    PackageUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"珠宝产品包装完成,包装盒编号:{packageData.PackageBoxNo}",
                    OutputData = packageData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "包装环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"包装异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : QualityInspectStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:质检业务环节
    /// </summary>
    public class QualityInspectStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "质检";

        private readonly ILogger<QualityInspectStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public QualityInspectStrategy(ILogger<QualityInspectStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行质检业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("质检环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(8);

                var inspectResult = new
                {
                    ProductNo = input.ProductNo,
                    InspectNo = $"Q-{input.BusinessId}",
                    Inspector = input.OperatorName,
                    Pass = true,
                    InspectUtcTime = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"产品质检完成,质检单号:{inspectResult.InspectNo},检验结果:合格",
                    OutputData = inspectResult
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "质检环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"质检异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : StockManageStrategy.cs 
 */
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:库存管理业务环节
    /// </summary>
    public class StockManageStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "库存管理";

        private readonly ILogger<StockManageStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public StockManageStrategy(ILogger<StockManageStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行库存管理业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("库存管理环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(9);

                var stockOutput = new
                {
                    BusinessId = input.BusinessId,
                    MaterialCode = input.MaterialCode,
                    ProductNo = input.ProductNo,
                    StockChangeQty = input.Quantity,
                    StockUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"库存业务处理完成,物料:{input.MaterialCode},产品:{input.ProductNo}",
                    OutputData = stockOutput
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "库存管理环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"库存业务异常:{ex.Message}"
                };
            }
        }
    }
}
/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : TrainStrategy.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Application.Strategies
{
    /// <summary>
    /// 策略:培训业务环节(支持部门)
    /// </summary>
    public class TrainStrategy : IBusinessStrategy
    {
        /// <summary>
        /// 业务环节名称
        /// </summary>
        public string PhaseName => "培训";

        private readonly ILogger<TrainStrategy> _logger;

        /// <summary>
        /// 构造注入日志
        /// </summary>
        /// <param name="logger">日志实例</param>
        public TrainStrategy(ILogger<TrainStrategy> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 执行培训业务
        /// </summary>
        /// <param name="input">业务输入DTO</param>
        /// <returns>执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
        {
            try
            {
                _logger.LogInformation("培训业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
                await Task.Delay(7);

                var trainOutput = new
                {
                    BusinessId = input.BusinessId,
                    Remark = input.Remark,
                    TrainUtc = DateTime.UtcNow
                };

                return new BusinessExecuteResultDto
                {
                    IsSuccess = true,
                    ErrorCode = 0,
                    Message = $"培训业务处理完成,备注:{input.Remark}",
                    OutputData = trainOutput
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "培训环节异常 BusinessId:{BusinessId}", input.BusinessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = 9999,
                    Message = $"培训业务异常:{ex.Message}"
                };
            }
        }
    }
}

  

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : ServiceCollectionExtension.cs 
 */

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Application.Services;
using StrategyPattern.Application.Strategies;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.Services;
using StrategyPattern.Infrastructure.Logging;
using StrategyPattern.Infrastructure.Repositories;
using StrategyPattern.Infrastructure.Resilience;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Infrastructure.Extensions
{
    /// <summary>
    /// DI扩展注册全部服务,分层注册,入口程序只调用该扩展,解耦依赖
    /// </summary>
    public static class ServiceCollectionExtension
    {
        /// <summary>
        /// 注册全部领域、应用、基础设施层服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="logRootPath">日志根目录</param>
        public static void AddJewelryEnterpriseServices(this IServiceCollection services, string logRootPath)
        {
            //日志配置
            services.AddLogging(logBuilder =>
            {
                logBuilder.ClearProviders();
                logBuilder.AddConsole();
                logBuilder.AddEnterpriseFileLogger(logRootPath);
                logBuilder.SetMinimumLevel(LogLevel.Debug);
            });

            #region 领域层注册
            services.AddScoped<MaterialDomainService>();
            services.AddScoped<IJewelryMaterialRepository, MemoryJewelryMaterialRepository>();
            services.AddScoped<IBusinessFlowRecordRepository, MemoryBusinessFlowRecordRepository>();
            services.AddScoped<IUnitOfWork, MemoryUnitOfWork>();
            #endregion

            #region 应用层注册
            //注册全部业务策略
            services.AddScoped<IBusinessStrategy, MaterialPurchaseVerifyStrategy>();
            services.AddScoped<IBusinessStrategy, DesignDrawStrategy>();
            services.AddScoped<IBusinessStrategy, ManufactureProduceStrategy>();
            services.AddScoped<IBusinessStrategy, QualityInspectStrategy>();
            services.AddScoped<IBusinessStrategy, PackageStrategy>();
            services.AddScoped<IBusinessStrategy, LogisticsStrategy>();
            services.AddScoped<IBusinessStrategy, FinanceSettleStrategy>();
            services.AddScoped<IBusinessStrategy, HumanResourceStrategy>();
            services.AddScoped<IBusinessStrategy, TrainStrategy>();
            services.AddScoped<IBusinessStrategy, StockManageStrategy>();
            services.AddScoped<IBusinessStrategy, MarketingStrategy>();

            services.AddScoped<BusinessStrategyContext>();
            services.AddScoped<JewelryFlowApplicationService>();
            #endregion

            #region 基础设施层
            services.AddScoped<IResilienceExecutor, CircuitBreakerResilienceExecutor>();
            #endregion
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : CustomLogFormatter.cs 
 */

using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Text;

namespace StrategyPattern.Infrastructure.Logging
{
    /// <summary>
    /// 自定义日志格式化器,保证控制台输出与文件日志输出格式完全一致(Karambolo v4 回调式接口)
    /// </summary>
    public class CustomLogFormatter : IFileLogEntryTextBuilder
    {
        /// <summary>
        /// 构建日志输出文本,文件日志与控制台共用一套格式
        /// </summary>
        public void BuildEntryText(
            StringBuilder sb,
            string category,
            LogLevel logLevel,
            EventId eventId,
            string message,
            Exception exception,
            IExternalScopeProvider scopeProvider,
            DateTimeOffset timestamp)
        {
            // 时间(使用服务器本地时间)
            sb.Append(timestamp.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            sb.Append(" | ");
            // 日志级别
            sb.Append(logLevel.ToString().PadRight(5));
            sb.Append(" | TID:");
            sb.Append(Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(3));
            sb.Append(" | ");
            // 分类器
            sb.Append(category);
            sb.Append(" | ");
            // 消息
            sb.Append(message);

            if (exception != null)
            {
                sb.AppendLine();
                sb.Append(exception.ToString());
            }
        }
    }
}/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : LoggerFactoryExtension.cs 
 */
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;

namespace StrategyPattern.Infrastructure.Logging
{
    /// <summary>
    /// 日志扩展方法,统一配置文件日志,按日期分文件夹,按级别分文件
    /// </summary>
    public static class LoggerFactoryExtension
    {
        /// <summary>
        /// 添加企业级结构化文件日志
        /// </summary>
        /// <param name="builder">日志构建器</param>
        /// <param name="logRootPath">日志根目录</param>
        public static void AddEnterpriseFileLogger(this ILoggingBuilder builder, string logRootPath)
        {
            if (!Directory.Exists(logRootPath))
            {
                Directory.CreateDirectory(logRootPath);
            }

            var customFormatter = new CustomLogFormatter();

            builder.AddFile(options =>
            {
                options.RootPath = logRootPath;
                options.Files = new[]
                {
                    new LogFileOptions
                    {
                        Path = "info/<date:yyyy-MM-dd>/app-info.log",
                        MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Information },
                        TextBuilder = customFormatter
                    },
                    new LogFileOptions
                    {
                        Path = "debug/<date:yyyy-MM-dd>/app-debug.log",
                        MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Debug },
                        TextBuilder = customFormatter
                    },
                    new LogFileOptions
                    {
                        Path = "warn/<date:yyyy-MM-dd>/app-warn.log",
                        MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Warning },
                        TextBuilder = customFormatter
                    },
                    new LogFileOptions
                    {
                        Path = "error/<date:yyyy-MM-dd>/app-error.log",
                        MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Error },
                        TextBuilder = customFormatter
                    }
                };
                options.FileAccessMode = LogFileAccessMode.KeepOpen;
            });
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MemoryBusinessFlowRecordRepository.cs 
 */

using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Infrastructure.Repositories
{
    /// <summary>
    /// 内存实现业务流程流水仓储,多线程安全
    /// </summary>
    public class MemoryBusinessFlowRecordRepository : IBusinessFlowRecordRepository
    {
        private readonly ConcurrentBag<BusinessFlowRecord> _recordBag;

        /// <summary>
        /// 构造初始化
        /// </summary>
        public MemoryBusinessFlowRecordRepository()
        {
            _recordBag = new ConcurrentBag<BusinessFlowRecord>();
        }

        /// <summary>
        /// 新增流程流水记录
        /// </summary>
        /// <param name="record">流水实体</param>
        public Task AddAsync(BusinessFlowRecord record)
        {
            _recordBag.Add(record);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 根据业务ID查询全部流水
        /// </summary>
        /// <param name="businessId">业务编号</param>
        /// <returns>流水集合</returns>
        public Task<List<BusinessFlowRecord>> QueryByBusinessIdAsync(long businessId)
        {
            var list = _recordBag.Where(r => r.BusinessId == businessId).ToList();
            return Task.FromResult(list);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MemoryJewelryMaterialRepository.cs 
 */
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Infrastructure.Repositories
{
    /// <summary>
    /// 内存实现原料仓储,并发安全,生产环境替换为EF Core/Dapper实现
    /// </summary>
    public class MemoryJewelryMaterialRepository : IJewelryMaterialRepository
    {
        /// <summary>
        /// 内存存储集合,线程安全
        /// </summary>
        private readonly ConcurrentDictionary<long, JewelryMaterial> _storeDict;

        /// <summary>
        /// 按物料编码索引
        /// </summary>
        private readonly ConcurrentDictionary<string, long> _codeToIdIndex;

        /// <summary>
        /// 构造初始化
        /// </summary>
        public MemoryJewelryMaterialRepository()
        {
            _storeDict = new ConcurrentDictionary<long, JewelryMaterial>();
            _codeToIdIndex = new ConcurrentDictionary<string, long>();
        }

        /// <summary>
        /// 根据ID获取原料
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns>实体或null</returns>
        public Task<JewelryMaterial?> GetByIdAsync(long id)
        {
            _storeDict.TryGetValue(id, out var entity);
            return Task.FromResult(entity);
        }

        /// <summary>
        /// 根据物料编码查询
        /// </summary>
        /// <param name="materialCode">物料编码</param>
        /// <returns>实体或null</returns>
        public Task<JewelryMaterial?> GetByCodeAsync(string materialCode)
        {
            if (_codeToIdIndex.TryGetValue(materialCode, out var id))
            {
                _storeDict.TryGetValue(id, out var entity);
                return Task.FromResult(entity);
            }
            return Task.FromResult<JewelryMaterial?>(null);
        }

        /// <summary>
        /// 添加原料实体
        /// </summary>
        /// <param name="entity">原料实体</param>
        public Task AddAsync(JewelryMaterial entity)
        {
            _storeDict.TryAdd(entity.Id, entity);
            _codeToIdIndex.TryAdd(entity.MaterialCode, entity.Id);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 更新原料实体
        /// </summary>
        /// <param name="entity">原料实体</param>
        public Task UpdateAsync(JewelryMaterial entity)
        {
            _storeDict[entity.Id] = entity;
            return Task.CompletedTask;
        }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : MemoryUnitOfWork.cs 
 */

using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Infrastructure.Repositories
{
    /// <summary>
    /// 内存版本工作单元,内存存储无真实事务,生产替换为EF Core实现
    /// </summary>
    public class MemoryUnitOfWork : IUnitOfWork
    {
        /// <summary>
        /// 提交变更,内存直接返回成功行数
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>受影响行数</returns>
        public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return Task.FromResult(1);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : CircuitBreakerResilienceExecutor.cs 
 */

using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.Infrastructure.Resilience
{
    /// <summary>
    /// 熔断器+指数退避重试执行器
    /// 多线程安全,三态:Closed关闭、Open熔断、HalfOpen半开
    /// </summary>
    public class CircuitBreakerResilienceExecutor : IResilienceExecutor
    {
        #region 内部状态定义
        /// <summary>
        /// 熔断器状态枚举
        /// </summary>
        private enum CircuitState
        {
            /// <summary>
            /// 关闭,正常通行
            /// </summary>
            Closed,
            /// <summary>
            /// 打开,熔断拦截
            /// </summary>
            Open,
            /// <summary>
            /// 半开,尝试放行少量请求探测恢复
            /// </summary>
            HalfOpen
        }
        #endregion

        private readonly ILogger<CircuitBreakerResilienceExecutor> _logger;

        /// <summary>
        /// 当前熔断器状态,volatile保证多线程可见
        /// </summary>
        private volatile CircuitState _circuitState;

        /// <summary>
        /// 失败计数,线程安全集合存储业务维度失败统计
        /// </summary>
        private readonly ConcurrentDictionary<long, int> _failCounterDict;

        /// <summary>
        /// 熔断打开的UTC时间戳
        /// </summary>
        private long _circuitOpenTimeUtcTicks;

        /// <summary>
        /// 最大失败阈值,超过该次数触发熔断
        /// </summary>
        private const int MaxFailThreshold = 3;

        /// <summary>
        /// 熔断冷却时间毫秒,熔断后等待多久进入半开状态
        /// </summary>
        private const int CircuitCoolDownMs = 5000;

        /// <summary>
        /// 最大重试次数
        /// </summary>
        private const int MaxRetryCount = 3;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志对象</param>
        public CircuitBreakerResilienceExecutor(ILogger<CircuitBreakerResilienceExecutor> logger)
        {
            _logger = logger;
            _circuitState = CircuitState.Closed;
            _failCounterDict = new ConcurrentDictionary<long, int>();
            _circuitOpenTimeUtcTicks = 0;
        }

        /// <summary>
        /// 带熔断重试包装执行业务委托
        /// </summary>
        /// <param name="businessFunc">业务异步委托</param>
        /// <param name="businessId">业务编号</param>
        /// <returns>业务执行结果DTO</returns>
        public async Task<BusinessExecuteResultDto> ExecuteWithResilienceAsync(Func<Task<BusinessExecuteResultDto>> businessFunc, long businessId)
        {
            //检查熔断器状态
            await CheckCircuitStateAsync();

            if (_circuitState == CircuitState.Open)
            {
                _logger.LogWarning("熔断器处于打开状态,直接拦截请求 BusinessId:{BusinessId}", businessId);
                return new BusinessExecuteResultDto
                {
                    IsSuccess = false,
                    ErrorCode = -10001,
                    Message = "系统熔断器已熔断,当前拒绝执行业务,请稍后重试"
                };
            }

            int currentRetry = 0;
            while (true)
            {
                try
                {
                    var result = await businessFunc.Invoke();
                    //业务成功,清除该业务失败计数
                    _failCounterDict.TryRemove(businessId, out _);

                    if (_circuitState == CircuitState.HalfOpen)
                    {
                        //半开状态下请求成功,关闭熔断器恢复正常
                        _circuitState = CircuitState.Closed;
                        _logger.LogInformation("熔断器半开探测成功,切换至Closed正常状态");
                    }
                    return result;
                }
                catch (Exception ex)
                {
                    currentRetry++;
                    int failCount = _failCounterDict.AddOrUpdate(businessId, 1, (k, v) => v + 1);
                    _logger.LogWarning(ex, "业务执行发生异常,重试次数:{Retry},失败计数:{FailCount},BusinessId:{BusinessId}",
                        currentRetry, failCount, businessId);

                    //达到失败阈值,打开熔断器
                    if (failCount >= MaxFailThreshold)
                    {
                        _circuitState = CircuitState.Open;
                        _circuitOpenTimeUtcTicks = DateTime.UtcNow.Ticks;
                        _logger.LogError("失败次数达到阈值,熔断器切换Open熔断状态 BusinessId:{BusinessId}", businessId);
                        return new BusinessExecuteResultDto
                        {
                            IsSuccess = false,
                            ErrorCode = -10002,
                            Message = $"连续失败{MaxFailThreshold}次,熔断器触发熔断"
                        };
                    }

                    if (currentRetry >= MaxRetryCount)
                    {
                        _logger.LogError("已到达最大重试次数,放弃重试 BusinessId:{BusinessId}", businessId);
                        return new BusinessExecuteResultDto
                        {
                            IsSuccess = false,
                            ErrorCode = -10003,
                            Message = $"重试{MaxRetryCount}次全部失败,业务执行失败,异常:{ex.Message}"
                        };
                    }

                    //指数退避休眠
                    int sleepMs = (int)(Math.Pow(2, currentRetry) * 100);
                    await Task.Delay(sleepMs);
                }
            }
        }

        /// <summary>
        /// 检查熔断器状态,处理Open→HalfOpen状态流转
        /// </summary>
        private Task CheckCircuitStateAsync()
        {
            if (_circuitState == CircuitState.Open)
            {
                var nowTicks = DateTime.UtcNow.Ticks;
                long elapsedMs = (nowTicks - _circuitOpenTimeUtcTicks) / TimeSpan.TicksPerMillisecond;
                if (elapsedMs >= CircuitCoolDownMs)
                {
                    _circuitState = CircuitState.HalfOpen;
                    _logger.LogInformation("熔断器冷却时间结束,切换为HalfOpen半开探测状态");
                }
            }
            return Task.CompletedTask;
        }
    }
}

  

调用:

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# 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/08/22 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : StrategyBll.cs 
 */

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Services;
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using StrategyPattern.Infrastructure.Extensions;
using System;
using System.Collections.Generic;
using System.Text;


namespace BLL
{


    public class StrategyBll
    {
        public async Task Demo()
        {
            //构建主机
            var host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) =>
                {
                    string logBase = Path.Combine(AppContext.BaseDirectory, "Logs");
                    services.AddJewelryEnterpriseServices(logBase);
                })
                .Build();

            //获取服务
            var scope = host.Services.CreateScope();
            var sp = scope.ServiceProvider;

            var flowService = sp.GetRequiredService<JewelryFlowApplicationService>();
            var materialRepo = sp.GetRequiredService<IJewelryMaterialRepository>();

            //初始化测试原料数据
            var testMaterial = JewelryMaterial.Create(
                id: 10001,
                materialCode: "MAT‑GEM‑0001",
                materialName: "天然蓝宝石原石",
                weightGram: 12.5m,
                qualityGrade: MaterialQualityGrade.GradeA,
                purchaseCost: Money.CreateCny(28600.00m));
               await materialRepo.AddAsync(testMaterial);

            //构建业务输入DTO
            var businessInput = new JewelryBusinessInputDto
            {
                BusinessId = 90001,
                BusinessPhase = "原料采购核验",
                MaterialCode = "MAT‑GEM‑0001",
                ProductNo = "PRO‑GEM‑0001",
                Quantity = 1,
                Amount = 52000.00m,
                OperatorId = 8001,
                OperatorName = "张工艺师",
                OperatorDepartment = "珠宝生产部",
                Remark = "蓝宝石首饰完整业务流水线测试",
                OccurTime = DateTime.Now
            };

            Console.WriteLine("==========开始执行珠宝完整业务流水线==========");
            var resultList = await flowService.ExecuteFullJewelryPipelineAsync(businessInput);

            foreach (var res in resultList)
            {
                Console.WriteLine($"成功:{res.IsSuccess} | 错误码:{res.ErrorCode} | 消息:{res.Message}");
            }

            Console.WriteLine("==========流水线执行完毕,按任意键退出==========");
            Console.ReadKey();
        }
    }
}

  

 

输出:

 

 

3a8d3df3-e165-4ebe-bbd0-ab88079dbcdb

 

posted @ 2026-09-10 22:14  ®Geovin Du Dream Park™  阅读(4)  评论(0)    收藏  举报