外观模式(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
相关产品推荐
相关产品推荐

