CSharp:Proxy Pattern
项目结构:

/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IJewelryBusinessService.cs
*/
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Domain.Abstractions
{
/// <summary>
/// 珠宝业务统一服务抽象主题(Subject)
/// 所有业务模块实现该接口,由代理统一拦截
/// </summary>
public interface IJewelryBusinessService
{
/// <summary>
/// 获取业务模块名称
/// </summary>
string GetModuleName();
/// <summary>
/// 获取当前模块所需权限编码
/// </summary>
string GetRequiredPermissionCode();
/// <summary>
/// 执行业务逻辑
/// </summary>
/// <param name="context">业务上下文</param>
/// <param name="businessOrderNo">业务单号</param>
/// <param name="businessParam">业务入参</param>
/// <returns>业务执行结果</returns>
Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam);
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessAuditRecord.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Domain.Models
{
/// <summary>
/// 业务操作审计记录实体
/// </summary>
public class BusinessAuditRecord
{
/// <summary>
/// 审计主键
/// </summary>
public long Id { get; set; }
/// <summary>
/// 追踪ID
/// </summary>
public string TraceId { get; set; } = string.Empty;
/// <summary>
/// 业务单号
/// </summary>
public string BusinessOrderNo { get; set; } = string.Empty;
/// <summary>
/// 业务模块名称
/// </summary>
public string ModuleName { get; set; } = string.Empty;
/// <summary>
/// 操作员编号
/// </summary>
public string OperatorId { get; set; } = string.Empty;
/// <summary>
/// 操作员名称
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 入参JSON
/// </summary>
public string InputParamJson { get; set; } = string.Empty;
/// <summary>
/// 返回结果JSON
/// </summary>
public string ResultJson { get; set; } = string.Empty;
/// <summary>
/// 执行耗时(ms)
/// </summary>
public long ElapsedMs { get; set; }
/// <summary>
/// 是否执行成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 异常信息
/// </summary>
public string? ExceptionMessage { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessContext.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Domain.Models
{
/// <summary>
/// 业务执行上下文
/// 携带操作员、租户、权限标识,供代理层权限校验、审计使用
/// </summary>
public class BusinessContext
{
/// <summary>
/// 当前操作人编号
/// </summary>
public string OperatorId { get; set; } = string.Empty;
/// <summary>
/// 操作员名称
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 租户编号
/// </summary>
public string TenantId { get; set; } = string.Empty;
/// <summary>
/// 请求唯一追踪ID,用于全链路追踪
/// </summary>
public string TraceId { get; set; } = Guid.NewGuid().ToString("N");
/// <summary>
/// 当前请求拥有的权限编码集合
/// </summary>
public HashSet<string> PermissionCodes { get; set; } = new HashSet<string>();
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryBusinessResult.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Domain.Models
{
/// <summary>
/// 珠宝业务统一返回模型
/// </summary>
public class JewelryBusinessResult
{
/// <summary>
/// 是否执行成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 返回消息
/// </summary>
public string Message { get; set; } = string.Empty;
/// <summary>
/// 业务自定义数据
/// </summary>
public object? Data { get; set; }
/// <summary>
/// 创建成功返回结果
/// </summary>
public static JewelryBusinessResult Ok(string msg, object? data = null)
{
return new JewelryBusinessResult
{
Success = true,
Message = msg,
Data = data
};
}
/// <summary>
/// 创建失败返回结果
/// </summary>
public static JewelryBusinessResult Fail(string msg, object? data = null)
{
return new JewelryBusinessResult
{
Success = false,
Message = msg,
Data = data
};
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IAuditRepository.cs
*/
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Audit
{
/// <summary>
/// 审计仓储接口,支持切换内存/数据库持久化
/// </summary>
public interface IAuditRepository
{
/// <summary>
/// 异步保存审计记录
/// </summary>
Task SaveAuditRecordAsync(BusinessAuditRecord record);
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MemoryAuditRepository.cs
*/
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Audit
{
/// <summary>
/// 内存审计仓储实现(线程安全)
/// 生产环境替换为SqlAuditRepository写入数据库
/// </summary>
public class MemoryAuditRepository : IAuditRepository
{
private readonly ConcurrentQueue<BusinessAuditRecord> _auditQueue = new();
public async Task SaveAuditRecordAsync(BusinessAuditRecord record)
{
// 模拟异步IO,真实场景替换为数据库写入
await Task.Yield();
_auditQueue.Enqueue(record);
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : HangfireTaskScheduler.cs
*/
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Models;
using ProxyPattern.Domain.Abstractions;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Hangfire
{
/// <summary>
/// Hangfire统一任务调度封装
/// 支持一次性任务、延迟任务、循环定时任务
/// </summary>
public class HangfireTaskScheduler
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly ILogger<HangfireTaskScheduler> _logger;
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly IRecurringJobManager _recurringJobManager;
public HangfireTaskScheduler(IServiceScopeFactory scopeFactory, ILogger<HangfireTaskScheduler> logger,
IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager)
{
_scopeFactory = scopeFactory;
_logger = logger;
_backgroundJobClient = backgroundJobClient;
_recurringJobManager = recurringJobManager;
}
/// <summary>
/// 调度单次执行业务流程任务
/// </summary>
/// <param name="context">业务上下文</param>
/// <param name="orderNo">业务单号</param>
/// <param name="param">业务参数</param>
public string EnqueueBusinessTask(BusinessContext context, string orderNo, Dictionary<string, object> param)
{
string jobId = _backgroundJobClient.Enqueue(() => ExecuteBusinessJob(context, orderNo, param));
_logger.LogInformation("Hangfire一次性任务已入队 JobId:{JobId},OrderNo:{OrderNo}", jobId, orderNo);
return jobId;
}
/// <summary>
/// 延迟执行任务
/// </summary>
public string ScheduleBusinessTask(BusinessContext context, string orderNo, Dictionary<string, object> param, TimeSpan delay)
{
string jobId = _backgroundJobClient.Schedule(() => ExecuteBusinessJob(context, orderNo, param), delay);
_logger.LogInformation("Hangfire延迟任务已创建 JobId:{JobId},Delay:{Delay}", jobId, delay);
return jobId;
}
/// <summary>
/// 循环定时任务(Cron表达式)
/// </summary>
public void RecurringBusinessTask(string recurringJobId, string cron, BusinessContext context, string orderNo, Dictionary<string, object> param)
{
_recurringJobManager.AddOrUpdate(recurringJobId, () => ExecuteBusinessJob(context, orderNo, param), cron);
_logger.LogInformation("Hangfire循环任务注册完成 RecurringId:{RecurringId},Cron:{Cron}", recurringJobId, cron);
}
/// <summary>
/// Hangfire执行入口(必须public,序列化调用)
/// </summary>
public async Task ExecuteBusinessJob(BusinessContext context, string orderNo, Dictionary<string, object> param)
{
using var scope = _scopeFactory.CreateScope();
var scheduler = scope.ServiceProvider.GetRequiredService<Scheduler.JewelryBusinessFlowScheduler>();
await scheduler.RunFullBusinessFlowAsync(context, orderNo, param);
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LogCleanBackgroundService.cs
*/
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Logging
{
/// <summary>
/// 日志自动清理后台服务
/// 定时扫描Logs目录,删除超过保留天数的日期文件夹,线程安全
/// </summary>
public class LogCleanBackgroundService : BackgroundService
{
private readonly ILogger<LogCleanBackgroundService> _logger;
private readonly string _logBasePath;
private readonly int _retainDays;
private readonly TimeSpan _scanInterval;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="logger">日志器</param>
/// <param name="logBasePath">日志根目录</param>
/// <param name="retainDays">日志保留天数</param>
/// <param name="scanInterval">扫描周期</param>
public LogCleanBackgroundService(ILogger<LogCleanBackgroundService> logger,
string logBasePath,
int retainDays = 30,
TimeSpan? scanInterval = null)
{
_logger = logger;
_logBasePath = Path.GetFullPath(logBasePath);
_retainDays = retainDays;
_scanInterval = scanInterval ?? TimeSpan.FromHours(6);
Directory.CreateDirectory(_logBasePath);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("日志清理后台服务启动,日志保留天数:{Days},扫描间隔:{Interval}",
_retainDays, _scanInterval);
while (!stoppingToken.IsCancellationRequested)
{
try
{
CleanExpiredLogs();
}
catch (Exception ex)
{
_logger.LogError(ex, "执行过期日志清理发生异常");
}
await Task.Delay(_scanInterval, stoppingToken);
}
_logger.LogInformation("日志清理后台服务停止");
}
/// <summary>
/// 执行清理逻辑
/// </summary>
private void CleanExpiredLogs()
{
var cutoffDate = DateTime.Now.AddDays(-_retainDays);
var dirs = Directory.GetDirectories(_logBasePath);
foreach (var dir in dirs)
{
var dirName = Path.GetFileName(dir);
if (!DateTime.TryParseExact(dirName, "yyyy-MM-dd", null,
System.Globalization.DateTimeStyles.None, out var folderDate))
{
continue;
}
if (folderDate < cutoffDate)
{
try
{
Directory.Delete(dir, true);
_logger.LogInformation("已删除过期日志目录:{Dir}", dir);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "删除日志目录失败 {Dir}", dir);
}
}
}
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : StructuredLogFormatter.cs
*/
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Logging
{
/// <summary>
/// 结构化JSON日志格式化器
/// 同时支持普通文本日志输出,保证控制台与文件日志格式对齐
/// </summary>
public static class StructuredLogFormatter
{
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
{
WriteIndented = false,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
/// <summary>
/// 生成文本格式日志(控制台、普通文件日志共用)
/// </summary>
public static string FormatPlainText(LogEntry<string> logEntry, Exception? ex)
{
string baseText = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{logEntry.LogLevel}] {logEntry.Category} > {logEntry.State}";
if (ex != null)
{
baseText += Environment.NewLine + ex.ToString();
}
return baseText;
}
/// <summary>
/// 生成结构化JSON日志字符串
/// </summary>
public static string FormatJson(LogEntry<string> logEntry, Exception? ex)
{
var logObj = new
{
Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
Level = logEntry.LogLevel.ToString(),
Category = logEntry.Category,
Message = logEntry.State,
Exception = ex?.ToString()
};
return JsonSerializer.Serialize(logObj, _jsonOptions);
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ConcurrentRateLimiter.cs
*/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.RateLimit
{
/// <summary>
/// 基于并发字典的简易滑动窗口限流(线程安全)
/// 企业级可替换为Redis分布式限流
/// </summary>
public class ConcurrentRateLimiter : IRateLimiter
{
/// <summary>
/// 单模块最大并发数量
/// </summary>
private readonly int _maxConcurrent;
private readonly ConcurrentDictionary<string, int> _concurrentCounter = new();
public ConcurrentRateLimiter(int maxConcurrent = 20)
{
_maxConcurrent = maxConcurrent;
}
public bool IsLimited(string moduleKey)
{
int current = _concurrentCounter.GetOrAdd(moduleKey, 0);
if (current >= _maxConcurrent)
{
return true;
}
_concurrentCounter.AddOrUpdate(moduleKey, 1, (k, v) => v + 1);
return false;
}
/// <summary>
/// 释放占用计数(业务执行完成后调用)
/// </summary>
public void Release(string moduleKey)
{
_concurrentCounter.AddOrUpdate(moduleKey, 0, (k, v) => Math.Max(0, v - 1));
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IRateLimiter.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.RateLimit
{
/// <summary>
/// 限流校验器接口
/// </summary>
public interface IRateLimiter
{
/// <summary>
/// 判断当前模块是否触发限流
/// </summary>
/// <param name="moduleKey">模块标识</param>
/// <returns>true=触发限流,false=允许通行</returns>
bool IsLimited(string moduleKey);
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IPermissionChecker.cs
*/
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Security
{
/// <summary>
/// 权限校验接口
/// </summary>
public interface IPermissionChecker
{
/// <summary>
/// 校验上下文是否拥有指定权限
/// </summary>
bool CheckPermission(BusinessContext context, string requiredPermissionCode);
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryPermissionChecker.cs
*/
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Infrastructure.Security
{
/// <summary>
/// 珠宝业务权限校验实现
/// </summary>
public class JewelryPermissionChecker : IPermissionChecker
{
public bool CheckPermission(BusinessContext context, string requiredPermissionCode)
{
if (string.IsNullOrEmpty(requiredPermissionCode))
return true;
return context.PermissionCodes.Contains(requiredPermissionCode);
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryBusinessServiceProxy.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using ProxyPattern.Infrastructure.Audit;
using ProxyPattern.Infrastructure.RateLimit;
using ProxyPattern.Infrastructure.Security;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Text.Json;
namespace ProxyPattern.Proxy
{
/// <summary>
/// 珠宝业务增强代理(Proxy Pattern)
/// 横切拦截顺序:限流 → 权限校验 → 执行业务 → 日志记录 → 审计入库 → 异常捕获
/// </summary>
/// <typeparam name="TRealService">真实业务实现类</typeparam>
public class JewelryBusinessServiceProxy<TRealService> : IJewelryBusinessService
where TRealService : class, IJewelryBusinessService
{
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
private readonly TRealService _realService;
private readonly ILogger<JewelryBusinessServiceProxy<TRealService>> _logger;
private readonly IPermissionChecker _permissionChecker;
private readonly IRateLimiter _rateLimiter;
private readonly IAuditRepository _auditRepository;
private readonly ConcurrentRateLimiter _concurrentRateLimiter;
public JewelryBusinessServiceProxy(TRealService realService,
ILogger<JewelryBusinessServiceProxy<TRealService>> logger,
IPermissionChecker permissionChecker,
IRateLimiter rateLimiter,
IAuditRepository auditRepository,
ConcurrentRateLimiter concurrentRateLimiter)
{
_realService = realService;
_logger = logger;
_permissionChecker = permissionChecker;
_rateLimiter = rateLimiter;
_auditRepository = auditRepository;
_concurrentRateLimiter = concurrentRateLimiter;
}
public string GetModuleName()
{
return _realService.GetModuleName();
}
public string GetRequiredPermissionCode()
{
return _realService.GetRequiredPermissionCode();
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
string moduleName = GetModuleName();
string permissionCode = GetRequiredPermissionCode();
string auditTraceId = context.TraceId;
Stopwatch stopwatch = Stopwatch.StartNew();
BusinessAuditRecord auditRecord = new BusinessAuditRecord
{
TraceId = auditTraceId,
BusinessOrderNo = businessOrderNo,
ModuleName = moduleName,
OperatorId = context.OperatorId,
OperatorName = context.OperatorName,
InputParamJson = JsonSerializer.Serialize(businessParam, _jsonOptions),
CreateTime = DateTime.Now
};
try
{
#region 1.限流拦截
if (_rateLimiter.IsLimited(moduleName))
{
string msg = $"【{moduleName}】模块触发并发限流,拒绝执行";
_logger.LogWarning("[{TraceId}][{Module}] {Msg}", auditTraceId, moduleName, msg);
auditRecord.Success = false;
auditRecord.ExceptionMessage = msg;
auditRecord.ResultJson = JsonSerializer.Serialize(JewelryBusinessResult.Fail(msg), _jsonOptions);
auditRecord.ElapsedMs = stopwatch.ElapsedMilliseconds;
await _auditRepository.SaveAuditRecordAsync(auditRecord);
return JewelryBusinessResult.Fail(msg);
}
#endregion
#region 2.权限校验拦截
if (!_permissionChecker.CheckPermission(context, permissionCode))
{
string msg = $"操作员无[{permissionCode}]权限,禁止访问模块:{moduleName}";
_logger.LogWarning("[{TraceId}][{Module}] {Msg}", auditTraceId, moduleName, msg);
auditRecord.Success = false;
auditRecord.ExceptionMessage = msg;
auditRecord.ResultJson = JsonSerializer.Serialize(JewelryBusinessResult.Fail(msg), _jsonOptions);
auditRecord.ElapsedMs = stopwatch.ElapsedMilliseconds;
await _auditRepository.SaveAuditRecordAsync(auditRecord);
return JewelryBusinessResult.Fail(msg);
}
#endregion
#region 3.执行业务
_logger.LogInformation("[{TraceId}][{Module}]业务开始,单号:{OrderNo},入参:{Param}",
auditTraceId, moduleName, businessOrderNo, auditRecord.InputParamJson);
var result = await _realService.ExecuteAsync(context, businessOrderNo, businessParam);
stopwatch.Stop();
auditRecord.ElapsedMs = stopwatch.ElapsedMilliseconds;
auditRecord.Success = result.Success;
auditRecord.ResultJson = JsonSerializer.Serialize(result, _jsonOptions);
if (result.Success)
{
_logger.LogInformation("[{TraceId}][{Module}]业务完成,单号:{OrderNo},耗时:{Ms}ms,信息:{Msg}",
auditTraceId, moduleName, businessOrderNo, stopwatch.ElapsedMilliseconds, result.Message);
}
else
{
_logger.LogWarning("[{TraceId}][{Module}]业务执行失败,单号:{OrderNo},耗时:{Ms}ms,信息:{Msg}",
auditTraceId, moduleName, businessOrderNo, stopwatch.ElapsedMilliseconds, result.Message);
}
await _auditRepository.SaveAuditRecordAsync(auditRecord);
return result;
#endregion
}
catch (Exception ex)
{
stopwatch.Stop();
_logger.LogError(ex, "[{TraceId}][{Module}]业务异常,单号:{OrderNo},耗时:{Ms}ms",
auditTraceId, moduleName, businessOrderNo, stopwatch.ElapsedMilliseconds);
auditRecord.ElapsedMs = stopwatch.ElapsedMilliseconds;
auditRecord.Success = false;
auditRecord.ExceptionMessage = ex.ToString();
auditRecord.ResultJson = JsonSerializer.Serialize(JewelryBusinessResult.Fail(ex.Message), _jsonOptions);
await _auditRepository.SaveAuditRecordAsync(auditRecord);
return JewelryBusinessResult.Fail($"模块[{moduleName}]运行异常:{ex.Message}");
}
finally
{
// 释放限流计数器
_concurrentRateLimiter.Release(moduleName);
}
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryBusinessFlowScheduler.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Scheduler
{
/// <summary>
/// 珠宝全业务流程调度器
/// 串联完整业务链路,支持手动调用与Hangfire任务调用
/// </summary>
public class JewelryBusinessFlowScheduler
{
private readonly IEnumerable<IJewelryBusinessService> _businessServices;
private readonly ILogger<JewelryBusinessFlowScheduler> _logger;
public JewelryBusinessFlowScheduler(IEnumerable<IJewelryBusinessService> businessServices, ILogger<JewelryBusinessFlowScheduler> logger)
{
_businessServices = businessServices;
_logger = logger;
}
/// <summary>
/// 顺序执行完整珠宝全业务流程
/// </summary>
public async Task RunFullBusinessFlowAsync(BusinessContext context, string orderNo, Dictionary<string, object> param)
{
_logger.LogInformation("[{TraceId}]==========开始执行珠宝全业务流程,单号:{OrderNo}==========", context.TraceId, orderNo);
foreach (var service in _businessServices)
{
var result = await service.ExecuteAsync(context, orderNo, param);
if (!result.Success)
{
_logger.LogError("[{TraceId}]流程中断,模块:{Module},原因:{Msg}", context.TraceId, service.GetModuleName(), result.Message);
break;
}
}
_logger.LogInformation("[{TraceId}]==========珠宝全业务流程执行结束,单号:{OrderNo}==========", context.TraceId, orderNo);
}
/// <summary>
/// 高并发批量模拟多订单并行执行
/// </summary>
public async Task RunConcurrentBusinessAsync(BusinessContext baseContext, int orderCount)
{
List<Task> taskList = new();
for (int i = 1; i <= orderCount; i++)
{
string orderNo = $"ORD-{DateTime.Now:yyyyMMdd}-{i:D6}";
var ctx = new BusinessContext
{
OperatorId = baseContext.OperatorId,
OperatorName = baseContext.OperatorName,
TenantId = baseContext.TenantId,
PermissionCodes = new HashSet<string>(baseContext.PermissionCodes)
};
var param = new Dictionary<string, object>
{
{"MaterialCode", "MAT-20260725-001"},
{"ProductStyle", "铂金钻石戒指"},
{"CustomerId", "CUS-89762"}
};
taskList.Add(RunFullBusinessFlowAsync(ctx, orderNo, param));
}
await Task.WhenAll(taskList);
_logger.LogInformation("全部并发订单执行完成");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessSaleService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 业务销售业务服务(真实主体 RealSubject)
/// </summary>
public class BusinessSaleService : IJewelryBusinessService
{
private readonly ILogger<BusinessSaleService> _logger;
public BusinessSaleService(ILogger<BusinessSaleService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "业务销售";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:SALE:ORDER";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(40, 130));
_logger.LogDebug("[{TraceId}]客户洽谈、销售订单录入、会员档案建立", context.TraceId);
if (!businessParam.ContainsKey("CustomerId"))
{
return JewelryBusinessResult.Fail("缺少客户编号,无法创建销售订单");
}
return JewelryBusinessResult.Ok("销售订单创建成功");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : FinanceService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 财务结算业务服务(真实主体 RealSubject)
/// </summary>
public class FinanceService : IJewelryBusinessService
{
private readonly ILogger<FinanceService> _logger;
public FinanceService(ILogger<FinanceService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "财务结算";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:FINANCE:SETTLE";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(50, 150));
_logger.LogDebug("[{TraceId}]成本核算、应收应付记账、票据单据生成", context.TraceId);
return JewelryBusinessResult.Ok("财务单据生成完成,结算流程办结");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : HrAdminService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 人事行政业务服务(真实主体 RealSubject)
/// </summary>
public class HrAdminService : IJewelryBusinessService
{
private readonly ILogger<HrAdminService> _logger;
public HrAdminService(ILogger<HrAdminService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "人事行政";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:HR:ADMIN";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(30, 90));
_logger.LogDebug("[{TraceId}]员工考勤、入职离职办理、薪酬核算、行政采购管理", context.TraceId);
return JewelryBusinessResult.Ok("人事行政流程办结");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ItOperationService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// IT运维业务服务(真实主体 RealSubject)
/// </summary>
public class ItOperationService : IJewelryBusinessService
{
private readonly ILogger<ItOperationService> _logger;
public ItOperationService(ILogger<ItOperationService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "IT运维";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:IT:OPS";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(20, 80));
_logger.LogDebug("[{TraceId}]系统巡检、门店设备维护、账号权限调整", context.TraceId);
return JewelryBusinessResult.Ok("IT运维工单处理完毕");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryDesignService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 珠宝设计制图业务服务(真实主体 RealSubject)
/// </summary>
public class JewelryDesignService : IJewelryBusinessService
{
private readonly ILogger<JewelryDesignService> _logger;
public JewelryDesignService(ILogger<JewelryDesignService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "设计制图";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:DESIGN:EDIT";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(80, 200));
_logger.LogDebug("[{TraceId}]根据客户需求生成珠宝3D图纸、渲染效果图", context.TraceId);
if (!businessParam.ContainsKey("ProductStyle"))
{
return JewelryBusinessResult.Fail("缺少产品款式参数,无法开展设计制图");
}
return JewelryBusinessResult.Ok("珠宝设计图纸定稿,可下发生产");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryLogisticsService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 珠宝物流配送业务服务(真实主体 RealSubject)
/// </summary>
public class JewelryLogisticsService : IJewelryBusinessService
{
private readonly ILogger<JewelryLogisticsService> _logger;
public JewelryLogisticsService(ILogger<JewelryLogisticsService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "物流配送";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:LOGISTICS:MANAGE";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(40, 120));
_logger.LogDebug("[{TraceId}]保价物流下单、运单创建、物流跟踪绑定", context.TraceId);
return JewelryBusinessResult.Ok("物流运单创建成功,商品出库配送");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryManufactureService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 珠宝加工生产业务服务(真实主体 RealSubject)
/// </summary>
public class JewelryManufactureService : IJewelryBusinessService
{
private readonly ILogger<JewelryManufactureService> _logger;
public JewelryManufactureService(ILogger<JewelryManufactureService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "加工生产";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:MANUFACTURE:EXEC";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(100, 300));
_logger.LogDebug("[{TraceId}]执行失蜡铸造、宝石镶嵌、抛光、电镀工序", context.TraceId);
return JewelryBusinessResult.Ok("珠宝加工生产工序全部完成,等待质检");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryPackService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 珠宝包装业务服务(真实主体 RealSubject)
/// </summary>
public class JewelryPackService : IJewelryBusinessService
{
private readonly ILogger<JewelryPackService> _logger;
public JewelryPackService(ILogger<JewelryPackService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "包装工序";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:PACK:OP";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(30, 100));
_logger.LogDebug("[{TraceId}]礼盒装配、证书放置、防伪标签封装", context.TraceId);
return JewelryBusinessResult.Ok("珠宝包装完成,待物流发货");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryQualityCheckService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 成品质检业务服务(真实主体 RealSubject)
/// </summary>
public class JewelryQualityCheckService : IJewelryBusinessService
{
private readonly ILogger<JewelryQualityCheckService> _logger;
public JewelryQualityCheckService(ILogger<JewelryQualityCheckService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "成品质检";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:QC:CHECK";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(60, 180));
_logger.LogDebug("[{TraceId}]尺寸校验、宝石牢固度、外观瑕疵、贵金属重量检测", context.TraceId);
return JewelryBusinessResult.Ok("成品质检合格,允许进入包装流程");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MarketingService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 营销推广业务服务(真实主体 RealSubject)
/// </summary>
public class MarketingService : IJewelryBusinessService
{
private readonly ILogger<MarketingService> _logger;
public MarketingService(ILogger<MarketingService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "营销推广";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:MARKETING:PUBLISH";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(60, 160));
_logger.LogDebug("[{TraceId}]新品宣传、会员优惠券推送、线上线下活动投放", context.TraceId);
return JewelryBusinessResult.Ok("营销推广活动执行完成");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : RawMaterialPurchaseService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 原料采购核验业务服务(真实主体 RealSubject)
/// </summary>
public class RawMaterialPurchaseService : IJewelryBusinessService
{
private readonly ILogger<RawMaterialPurchaseService> _logger;
public RawMaterialPurchaseService(ILogger<RawMaterialPurchaseService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "原料采购核验";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:RAW_MATERIAL:PURCHASE";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(50, 150));
_logger.LogDebug("[{TraceId}]原料入库核验:贵金属纯度、宝石证书查验", context.TraceId);
if (!businessParam.ContainsKey("MaterialCode"))
{
return JewelryBusinessResult.Fail("缺少原料编码,采购核验不通过");
}
return JewelryBusinessResult.Ok("原料采购核验完成,准予入库");
}
}
}
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : StaffTrainService.cs
*/
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyPattern.Services
{
/// <summary>
/// 员工培训业务服务(真实主体 RealSubject)
/// </summary>
public class StaffTrainService : IJewelryBusinessService
{
private readonly ILogger<StaffTrainService> _logger;
public StaffTrainService(ILogger<StaffTrainService> logger)
{
_logger = logger;
}
public string GetModuleName()
{
return "员工培训";
}
public string GetRequiredPermissionCode()
{
return "JEWELRY:TRAIN:MANAGE";
}
public async Task<JewelryBusinessResult> ExecuteAsync(BusinessContext context, string businessOrderNo, Dictionary<string, object> businessParam)
{
await Task.Delay(Random.Shared.Next(50, 140));
_logger.LogDebug("[{TraceId}]珠宝专业知识、销售话术、质检标准培训任务执行", context.TraceId);
return JewelryBusinessResult.Ok("员工培训任务完成登记");
}
}
}
调用:
/**
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 代理模式Proxy 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/12 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ProxyBll.cs
*/
using Hangfire;
using Hangfire.MemoryStorage;
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ProxyPattern.Domain.Abstractions;
using ProxyPattern.Infrastructure.Audit;
using ProxyPattern.Infrastructure.Hangfire;
using ProxyPattern.Infrastructure.Logging;
using ProxyPattern.Infrastructure.RateLimit;
using ProxyPattern.Infrastructure.Security;
using ProxyPattern.Proxy;
using ProxyPattern.Scheduler;
using ProxyPattern.Services;
using ProxyPattern.Domain.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
namespace BLL
{
public class ProxyBll
{
/// <summary>
/// 统一注册业务代理
/// </summary>
private static void RegisterBusinessProxy<TReal>(IServiceCollection services)
where TReal : class, IJewelryBusinessService
{
services.AddTransient<IJewelryBusinessService, JewelryBusinessServiceProxy<TReal>>(sp =>
{
var real = sp.GetRequiredService<TReal>();
var logger = sp.GetRequiredService<ILogger<JewelryBusinessServiceProxy<TReal>>>();
var permChecker = sp.GetRequiredService<IPermissionChecker>();
var rateLimiter = sp.GetRequiredService<IRateLimiter>();
var auditRepo = sp.GetRequiredService<IAuditRepository>();
var concurrentLimiter = sp.GetRequiredService<ConcurrentRateLimiter>();
return new JewelryBusinessServiceProxy<TReal>(real, logger, permChecker, rateLimiter, auditRepo, concurrentLimiter);
});
}
/// <summary>
///
/// </summary>
public async void Demo()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
const string LogBasePath = "Logs";
const int LogRetainDays = 30;
var host = Host.CreateDefaultBuilder(Array.Empty<string>())
.ConfigureLogging((context, loggingBuilder) =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddConsole();
loggingBuilder.AddFile(fileBuilder =>
{
fileBuilder.RootPath = Directory.GetCurrentDirectory();
string todayDate = DateTime.Now.ToString("yyyy-MM-dd");
fileBuilder.Files = new[]
{
new LogFileOptions { Path = $"{LogBasePath}/{todayDate}/app-debug.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Debug } },
new LogFileOptions { Path = $"{LogBasePath}/{todayDate}/app-info.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Information } },
new LogFileOptions { Path = $"{LogBasePath}/{todayDate}/app-warn.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Warning } },
new LogFileOptions { Path = $"{LogBasePath}/{todayDate}/app-error.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Error } }
};
});
loggingBuilder.SetMinimumLevel(LogLevel.Debug);
})
.ConfigureServices((ctx, services) =>
{
#region 基础设施注册
services.AddSingleton<IPermissionChecker, JewelryPermissionChecker>();
services.AddSingleton<IAuditRepository, MemoryAuditRepository>();
services.AddSingleton<ConcurrentRateLimiter>(_ => new ConcurrentRateLimiter(20));
services.AddSingleton<IRateLimiter>(sp => sp.GetRequiredService<ConcurrentRateLimiter>());
// 日志清理后台服务
services.AddHostedService(sp =>
new LogCleanBackgroundService(sp.GetRequiredService<ILogger<LogCleanBackgroundService>>(),
LogBasePath, LogRetainDays));
// Hangfire 内存存储
services.AddHangfire(config =>
{
config.SetDataCompatibilityLevel(CompatibilityLevel.Version_180);
config.UseMemoryStorage();
});
services.AddHangfireServer();
services.AddTransient<HangfireTaskScheduler>();
#endregion
#region 注册真实业务服务
services.AddTransient<RawMaterialPurchaseService>();
services.AddTransient<JewelryDesignService>();
services.AddTransient<JewelryManufactureService>();
services.AddTransient<JewelryQualityCheckService>();
services.AddTransient<JewelryPackService>();
services.AddTransient<JewelryLogisticsService>();
services.AddTransient<FinanceService>();
services.AddTransient<MarketingService>();
services.AddTransient<BusinessSaleService>();
services.AddTransient<HrAdminService>();
services.AddTransient<ItOperationService>();
services.AddTransient<StaffTrainService>();
#endregion
#region 代理模式注册工厂方法
RegisterBusinessProxy<RawMaterialPurchaseService>(services);
RegisterBusinessProxy<JewelryDesignService>(services);
RegisterBusinessProxy<JewelryManufactureService>(services);
RegisterBusinessProxy<JewelryQualityCheckService>(services);
RegisterBusinessProxy<JewelryPackService>(services);
RegisterBusinessProxy<JewelryLogisticsService>(services);
RegisterBusinessProxy<FinanceService>(services);
RegisterBusinessProxy<MarketingService>(services);
RegisterBusinessProxy<BusinessSaleService>(services);
RegisterBusinessProxy<HrAdminService>(services);
RegisterBusinessProxy<ItOperationService>(services);
RegisterBusinessProxy<StaffTrainService>(services);
#endregion
services.AddTransient<JewelryBusinessFlowScheduler>();
})
.Build();
// 测试上下文
var testContext = new BusinessContext
{
OperatorId = "OP001",
OperatorName = "珠宝管理员",
TenantId = "T001",
PermissionCodes = new HashSet<string>
{
"JEWELRY:RAW_MATERIAL:PURCHASE",
"JEWELRY:DESIGN:EDIT",
"JEWELRY:MANUFACTURE:EXEC",
"JEWELRY:QC:CHECK",
"JEWELRY:PACK:OP",
"JEWELRY:LOGISTICS:MANAGE",
"JEWELRY:FINANCE:SETTLE",
"JEWELRY:MARKETING:PUBLISH",
"JEWELRY:SALE:ORDER",
"JEWELRY:HR:ADMIN",
"JEWELRY:IT:OPS",
"JEWELRY:TRAIN:MANAGE"
}
};
var scheduler = host.Services.GetRequiredService<JewelryBusinessFlowScheduler>();
var hangfireScheduler = host.Services.GetRequiredService<HangfireTaskScheduler>();
Console.WriteLine("=====启动并发业务测试=====");
await scheduler.RunConcurrentBusinessAsync(testContext, 5);
// 演示Hangfire一次性任务入队
hangfireScheduler.EnqueueBusinessTask(testContext, "HANG-ORD-001", new Dictionary<string, object>
{
{"MaterialCode", "MAT-HF-001"}
});
Console.WriteLine("执行完成,按任意键退出");
Console.ReadKey();
await host.StopAsync();
}
}
}
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号