You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#带保护方法的类继承设计与运行时基类处理器问题

问题分析

你的核心矛盾在于:

  1. 原有SecretConfigurations同时用继承(继承BaseConfigurations)和依赖注入(注入ICRUDHandler),但注入的实例是独立对象,无法触发SecretConfigurations重写的ProtectedMethod——因为实例方法属于当前对象,注入的BaseConfigurations/V2和SecretConfigurations是两个完全独立的实例。
  2. 为BaseConfigurationsV2单独写SecretConfigurationsV2会重复所有Secret相关逻辑,违反DRY原则。

下面是两种无代码重复的解决方案:


方案1:装饰器模式(推荐)

把Secret相关逻辑抽成装饰器类,实现ICRUDHandler接口,内部持有任意ICRUDHandler实例(BaseConfigurations或V2),通过组合而非继承来复用Secret逻辑,适配所有CRUD实现版本。

代码实现

// 定义Secret装饰器,实现ICRUDHandler
public class SecretCRUDHandlerDecorator : ICRUDHandler
{
    private readonly ICRUDHandler _innerHandler;

    // 构造函数注入任意ICRUDHandler实例
    public SecretCRUDHandlerDecorator(ICRUDHandler innerHandler)
    {
        _innerHandler = innerHandler;
    }

    // 实现CreateSetting,添加Secret专属逻辑
    public void CreateSetting(Setting setting)
    {
        // 原ProtectedMethod中的Secret前置逻辑
        ApplySecretPreProcessing(setting);
        
        // 调用内部handler的原生Create逻辑
        _innerHandler.CreateSetting(setting);
        
        // 可选:Secret后置逻辑
        ApplySecretPostProcessing(setting);
    }

    // 实现GetSetting,添加解密逻辑
    public Setting GetSetting(string key)
    {
        var setting = _innerHandler.GetSetting(key);
        // Secret专属解密逻辑
        DecryptSetting(setting);
        return setting;
    }

    // 其他CRUD方法(Update/Delete)同理,按需添加Secret逻辑后调用_innerHandler对应方法
    public void UpdateSetting(Setting setting)
    {
        ApplySecretPreProcessing(setting);
        _innerHandler.UpdateSetting(setting);
    }

    // Secret专属逻辑封装为私有方法,只写一次
    private void ApplySecretPreProcessing(Setting setting)
    {
        // 原SecretConfigurations中ProtectedMethod的逻辑
        // 例如:加密敏感字段、校验权限等
    }

    private void ApplySecretPostProcessing(Setting setting)
    {
        // 例如:记录审计日志、清理临时数据等
    }

    private void DecryptSetting(Setting setting)
    {
        // 解密敏感字段逻辑
    }
}

使用方式

运行时选择基础CRUD实例,再用装饰器包装成Secret版本:

// 运行时切换Base或V2实例
ICRUDHandler baseHandler = someCondition ? new BaseConfigurations() : new BaseConfigurationsV2();
// 包装为Secret版本,无需新增子类
ICRUDHandler secretHandler = new SecretCRUDHandlerDecorator(baseHandler);

优势

  • Secret逻辑只写一次,适配所有ICRUDHandler实现,新增CRUD版本时无需修改Secret代码
  • 完全解耦Secret逻辑与基础CRUD逻辑,符合单一职责原则
  • 避免继承带来的耦合,用组合实现灵活扩展

方案2:提取Secret逻辑为独立服务

把Secret逻辑抽成独立服务,让BaseConfigurations和V2通过依赖注入复用该服务,无需额外子类。

代码实现

  1. 定义Secret处理器接口与实现:
public interface ISecretProcessor
{
    void PreProcessSetting(Setting setting);
    void PostProcessSetting(Setting setting);
    void DecryptSetting(Setting setting);
}

public class SecretProcessor : ISecretProcessor
{
    public void PreProcessSetting(Setting setting)
    {
        // 原ProtectedMethod中的Secret前置逻辑
    }

    public void PostProcessSetting(Setting setting)
    {
        // Secret后置逻辑
    }

    public void DecryptSetting(Setting setting)
    {
        // 解密逻辑
    }
}
  1. 修改基础CRUD类,注入ISecretProcessor:
public class BaseConfigurations : ICRUDHandler
{
    protected readonly ISecretProcessor _secretProcessor;

    // 可选注入,兼容普通场景和Secret场景
    public BaseConfigurations(ISecretProcessor secretProcessor = null)
    {
        _secretProcessor = secretProcessor;
    }

    public virtual void CreateSetting(Setting setting)
    {
        // 存在Secret处理器时执行前置逻辑
        _secretProcessor?.PreProcessSetting(setting);
        
        // 原生Create逻辑
        // ...
        
        _secretProcessor?.PostProcessSetting(setting);
    }

    public virtual Setting GetSetting(string key)
    {
        var setting = // 原生读取逻辑;
        _secretProcessor?.DecryptSetting(setting);
        return setting;
    }
}

// BaseConfigurationsV2自动继承对ISecretProcessor的依赖
public class BaseConfigurationsV2 : BaseConfigurations
{
    public BaseConfigurationsV2(ISecretProcessor secretProcessor = null) : base(secretProcessor)
    {
    }

    // 仅重写V2专属的CRUD逻辑,无需重复Secret代码
    public override void CreateSetting(Setting setting)
    {
        _secretProcessor?.PreProcessSetting(setting);
        
        // V2专属Create逻辑
        // ...
        
        _secretProcessor?.PostProcessSetting(setting);
    }
}

使用方式

根据场景选择是否注入SecretProcessor:

// 普通场景
ICRUDHandler normalHandler = someCondition ? new BaseConfigurations() : new BaseConfigurationsV2();

// Secret场景
var secretProcessor = new SecretProcessor();
ICRUDHandler secretHandler = someCondition ? new BaseConfigurations(secretProcessor) : new BaseConfigurationsV2(secretProcessor);

优势

  • Secret逻辑集中管理,无重复代码
  • 保留基础CRUD类的继承关系,同时通过依赖注入解耦Secret逻辑
  • 兼容普通和Secret两种场景

内容的提问来源于stack exchange,提问作者CodeMonkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:44:52