应该将类接口放在.NET类库中的哪个位置?

时间:2012-01-10 08:30:42

标签: c# design-patterns interface

我很好奇开发人员的意见/实践,理想情况下,类接口应放在.NET类库中。它们是否应该包含在解决方案中的专用库中,例如MyCompany.AccountPackage.Interfaces?

他们是否应拥有自己的名称空间,例如MyCompany.AccountPackage.MasterAccounts.Interfaces?

还有其他想法/意见吗?

是否有任何好的指南演示如何构建.Net库(甚至更好的解决方案),通常显示标准库中通常应该公开哪些类/接口。

谢谢, d。

4 个答案:

答案 0 :(得分:8)

简短回答:

接口应该接近它们的实现位置。

至少有一些BCL执行此操作 - 例如,IEnumerable<T>位于System.Collections.Generic命名空间中。


答案稍长:

这取决于接口的用途。

是否为第三方提供插件接口(a-la the provider model或MEF)?

如果是这样,一个单独的程序集就有意义,所以第三方需要导入的就是这个程序集。

它是内部的,用于测试和IoC目的吗?

我认为保持接近实现是有意义的,在组织上有助于保持代码与接口同步。

答案 1 :(得分:1)

它认为答案是上下文的,因为它取决于接口的用途以及它们如何适合您的库的体系结构。

对象模型

在我看来,如果要创建某种形式的对象模型,则应将表示对象模型的接口放在程序集中的一个项目中。这样,可以重新分配和编码对接口的引用,而不必担心实际的实现,这可能会有所不同。它还允许您提供对象模型的初始实现,同时允许其他人重新实现(可能支持新平台或相关软件)。

通用

如果您打算创建类似于.NET System.Collections.Generic命名空间中的界面,那么这些界面将在许多地方重复使用;那么我建议把它放得足够低,以便多个项目可以访问和实现界面。但是,这并不意味着您无法在同一项目中自行实现该接口。在这种情况下,这一切都取决于你打算在那个集会中的内容。

其他用途

另一种用途可能是某些数据库交互系统,其中您有一个定义某个数据库交互器的接口,但您可能有两个或更多实现它。例如,您可能有一个专门与Microsoft Access数据库交互,一个与Sql数据库交互。在这种情况下,在同一个程序集中提供您的接口实现是可行的。

所有这一切,都取决于具体情况和预期用途。我发现确定它是什么的最佳方法是创建一个原型版本的程序集,看看你可能需要如何使用它。

答案 2 :(得分:1)

与大多数情况一样:取决于。

但在99%的情况下,我将接口放入自己的程序集中,并将其分组为逻辑单元以防止严格的接口依赖性。 在过去,我只是将它放在第一个实现的地方。这成了一个紧密耦合的混乱,以后不可能分开。

如果您练习/争取松耦合,我建议将接口移动到单独的组件。 我更喜欢只包括:

  • 接口,
  • 枚举
  • 常数
  • 接口的扩展方法(不依赖于具体实现)
  • &#34;稳定&#34;类和结构(即永远不会改变或继承的那些)

进入&#34;接口组件&#34;并且仅供参考:

  • 其他&#34;接口程序集&#34;
  • &#34;工具组件&#34; (它应该只包含扩展方法,常量等稳定的东西)

这不适用于仅在一个程序集中使用的内部使用的接口(将是接口的1%)。

可以包含在与接口本身相同的程序集中的唯一实现是:

  • 并不依赖于其他非界面程序集(您不希望包含使用界面程序集的内容,而这些界面程序集只是您不想使用的一个实现所需要的)。
  • 是某种默认或无操作实现

&#34;实施程序集&#34;只应在主程序集中引用,其他程序集仅包括接口程序集。这也可以确保您不直接使用该实现或测试该接口是否属于此特殊实现。

为什么呢?这样,您的程序集仅依赖于稳定的程序集,并且不会紧密耦合。如果您计划使用依赖注入,这也是首选方法。

命名空间:

您应该将实现放在接口的子命名空间中。所以,为了了解你的例子,我建议:

  • 将界面放在MyCompany.AccountPackage.MasterAccounts
  • MyCompany.AccountPackage.MasterAccounts
  • 中添加扩展方法,此接口的其他稳定内容
  • 将实现放入正确命名的子命名空间MyCompany.AccountPackage.MasterAccounts.SQLMasterAccountsMyCompany.AccountPackage.MasterAccounts.Implementation

为什么?

从实现方面来看,这意味着,您无需使用using MyCompany.AccountPackage.MasterAccounts.Interfaces即可获得所有接口和扩展程序。

从客户端来看,这意味着您将在实现程序集中避免使用intellisense中的太多选项(无论如何不应包括其他实现程序集),而是可以轻松访问主程序集中的实现,您可以选择要使用的具体实现。

答案 3 :(得分:0)

请参阅以下帖子:

Proper .NET DLL structure for app

并且,通常会尝试回答以下问题:

  1. 多个程序集会使用这些接口吗?

  2. 你可以减少否。装配和参考文献?

  3. 您是否尝试将不相关的接口包含在单个程序集中,只是为了减少dll计数?

  4. 您是否考虑过可扩展性和维护?