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

外观模式(Facade Pattern)可访问性不一致错误的解决与架构疑问

C#外观模式实现问题解答

问题1:如何消除"Inconsistent accessibility"错误?

错误根源是public构造函数的参数类型(IServiceA/IServiceB为internal)比构造函数本身的访问级别更低——外部代码(如不同程序集的应用层)无法识别这些internal类型,自然无法调用该public构造函数。

解决方案:

  • 将Facade的构造函数改为internal,限制仅同程序集代码能直接实例化它,外部仅通过IFacade接口交互
  • 搭配依赖注入(DI)容器使用:在基础设施层(与Facade同程序集)完成IFacade、Facade及内部IServiceA/IServiceB实现的注册;应用层仅依赖IFacade接口,由DI容器负责注入实例,无需感知底层internal服务的存在

修正后的核心代码:

public interface IFacade
{
    void TestA();
    void TestB();
}

// 构造函数改为internal
public class Facade : IFacade
{
    private readonly IServiceA _serviceA;
    private readonly IServiceB _serviceB;

    internal Facade(IServiceA serviceA, IServiceB serviceB)
    {
        _serviceA = serviceA;
        _serviceB = serviceB;
    }

    public void TestA()
    {
        // 修正原代码笔误:_service → _serviceA
        _serviceA.DoA1();
        _serviceA.DoA2();
    }

    public void TestB()
    {
        // 修正原代码笔误:_service.DoA() → _serviceB.DoB1()
        _serviceB.DoB1();
    }
}

// 保持底层服务为internal
internal interface IServiceA
{
    void DoA1();
    void DoA2();
}

internal class ServiceA : IServiceA
{
    public void DoA1() { }
    public void DoA2() { }
}

internal interface IServiceB
{
    void DoB1();
}

internal class ServiceB : IServiceB
{
    public void DoB1() { }
}

DI注册示例(基础设施层内):

// 以Microsoft.Extensions.DependencyInjection为例
services.AddScoped<IServiceA, ServiceA>();
services.AddScoped<IServiceB, ServiceB>();
services.AddScoped<IFacade, Facade>();

问题2:IFacade与Facade的分层位置

遵循Clean Architecture的依赖规则:

  • IFacade放在应用层:应用层定义业务所需的抽象接口,明确对外暴露的功能边界,不涉及具体实现细节
  • Facade实现放在基础设施层:Facade是对底层子系统(基础设施层的internal服务)的封装,属于具体实现逻辑,依赖底层服务,符合"基础设施层依赖应用层抽象"的核心方向

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:42:23