C# 不允许使用任意实现时使用接口隐藏实现详细信息

C# 不允许使用任意实现时使用接口隐藏实现详细信息,c#,api,oop,C#,Api,Oop,我正在使用C#为我们的应用程序构建一个公共API。我在WCF客户端使用的DTO之上有一组facade类。它允许API使用者从数据库应用程序获取、更新、创建等。标准物品:客户有订单集合,订单有行项目集合,等等 facade类都派生自一个公共基类,并重写执行验证、读取/写入DTO和其他管道工作的方法,所有这些都使用各种内部类型。我使用工厂创建新对象并获取现有对象 现在的问题是如何最好地通过API公开类,同时最小化实现细节的公开 接口似乎是一种显而易见的方法,是限制暴露内容的最简单方法(而且最终可能是

我正在使用C#为我们的应用程序构建一个公共API。我在WCF客户端使用的DTO之上有一组facade类。它允许API使用者从数据库应用程序获取、更新、创建等。标准物品:客户有订单集合,订单有行项目集合,等等

facade类都派生自一个公共基类,并重写执行验证、读取/写入DTO和其他管道工作的方法,所有这些都使用各种内部类型。我使用工厂创建新对象并获取现有对象

现在的问题是如何最好地通过API公开类,同时最小化实现细节的公开

接口似乎是一种显而易见的方法,是限制暴露内容的最简单方法(而且最终可能是必要的,因为COM兼容接口正在考虑之中)。接口方法的问题是,在内部,我的代码将依赖于接口的特定实现

假设我有一个ICCustomer接口公开我的CustomerFacade,IOrder公开OrderFacade。在外部,ICustomer有一个iOrder集合。但是在内部,CustomerFacade有一个OrderFacades集合。如果客户端应用程序向客户添加新的IOrder,我必须检查IOrder是否确实是以前从我的工厂创建的OrderFacade,而不是实现IOrder的我无法控制的其他对象。这是因为在内部,我需要一个命令,以便能够做比IOrder更多的事情

实际上,这并不重要——API的用户不会试图创建自己的订单实现。但我觉得这很不雅观,就像是对接口契约的滥用

直接公开facade类并不好,因为必须公开整个类层次结构以及受保护方法使用的内部类型,这会使API中的类型变得杂乱无章,而使用者不会使用这些类型,也不需要知道这些类型

我能想到的另一种选择是另一层封装:一个包含私有OrderFacade的订单,它只公开应该是公共的成员。但这似乎是为了有限的利益而编写的大量额外代码

我考虑过抽象基类,但由于继承结构的原因,这并不比公开facade类更好。例如,如果我有一个从CatalogItem继承的ServiceItem,在两者之间引入一个抽象ServiceItemBase仍然需要我公开CatalogItem中所有受保护的方法


有没有关于这些方法的建议,或者我没有看过的替代方案?

这似乎相当复杂。我不知道你要解决的业务问题,所以我不知道为什么需要各种各样的外观。如果用户将使用API进行数据操作,则可以考虑使用命令修改数据,以及查询返回只包含客户端需要的数据的DTO。p>


这是一本可能会有所帮助的好书。

您还可以公开没有公共构造函数而没有接口的抽象类。这还有一个额外的优点,即抽象类可以作为非破坏性更改进行扩展,这对于接口来说是不正确的


使用内部访问修饰符可以隐藏在实现程序集外部不可见的成员。

您可以始终实现OrderFacade,使其可以使用OrderId构造,而完全忽略接口。你的客户不会重新发明你的订单是如何运作的,他们只是想输入一个数字并得到一个答案。看看微软自己的C#API——很少有接口,只有在需要时才有,比如COM,你仍然不知道或不关心它们是如何工作的。您只需要给Word API一个文件名并取回Word文档,而不是实现IDocumentyourself@StenPetrov谢谢,但我不明白这如何解决如何最好地隐藏我不想泄露到API中的内部细节的问题。你已经有了服务——这就是大部分(如果不是全部的话)魔法应该发生的地方。API的客户端应该主要用于促进对服务的调用(验证、配置处理等)。我说的是不要过度抽象(接口、抽象类、工厂等);我已经更新以解决这个问题。抽象基在这里对我来说不起作用,因为它们仍然从它们上面的类继承(从而暴露这些类的受保护成员)。这不是提供内部访问修饰符的原因吗?很好。我可以将所有受保护的成员改为内部成员。这暴露了程序集中类之外的一些内容,但在本例中这不是一个大问题。看起来是一个很好的参考。我会看一看,看有没有什么我可以申请的。