【问题标题】:A good TDD-Friendly .NET file IO library [closed]一个良好的 TDD 友好 .NET 文件 IO 库 [关闭]
【发布时间】:2009-07-07 19:31:41
【问题描述】:

正如你们许多人所知,System.IO 命名空间的设计非常糟糕。我想要一个免费的库,它以一种理智的方式包装文件 IO 功能(阅读:不需要你到处传递字符串)。我记得前段时间读到,已经编写了一小部分这样的库(作者很惊讶没有更多的库)。我认为是devliciouscodebetterLos Techies 上的其中一个人做了其中之一。

有谁知道我在说什么或另一个好的 File IO 包装器?

编辑:我想我应该指定我进行测试驱动开发,我的担忧主要(但不完全)围绕 System.IO 的测试友好性。

【问题讨论】:

  • 我很想听听您说 System.IO 命名空间是“经过精心设计的”的理由。我个人发现它的设计非常好,大多数 BCL 也是如此。
  • 它只是一堆静态类的方法——几乎没有 OO-y。如果不为其功能编写包装器,几乎不可能对执行文件处理的类进行单元测试。几乎没有网站界面。
  • FileInfo 不是静态类。
  • 约翰,请在下面查看我对您的回答的回复。 FileInfo 确实是一个更好的故事,但只有一点点。实体、提供者、服务以及基本上所有内容之间仍然存在紧密耦合。
  • 投票我完全同意 System.IO 很糟糕。

标签: .net open-source file-io


【解决方案1】:

System.IO.FileInfo 有什么问题?


我很好奇,所以开始使用 ReSharper 创建一组包装器。花了我16分钟,我没有测试过,不知道是否满足你的需求。不过,我想我应该概述一下我使用的过程:

  1. 新建类库项目
  2. 公开 Class1 并将其重命名为 FileSystemInfoWrapper
  3. 给它一个 FileSystemInfo 类型的私有字段 _fsi(解析类以获取导入的命名空间)
  4. 单击字段并选择在构造函数中初始化
  5. 再次单击该字段并使用 ReSharper -> 代码 -> 生成 (Alt+Ins);选择生成委托成员;点击“公开”获取所有公开成员
  6. 与 FileInfo 相同,但也派生自 FileSystemInfoWrapper 并删除重复的成员(ReSharper 在这里可以做得更好)
  7. 与 DirectoryInfo 相同,但也派生自 FileSystemInfoWrapper 并修复重复项
  8. 对于每个包装器,单击类,然后使用 ReSharper->Refactor->Extract Interface
  9. 让 IFileInfoWrapper 和 IDirectoryInfoWrapper 从 IFileSystemInfoWrapper 派生,并删除重复项。

结果是包含相应类的方法和属性的接口,以及委托给原始类并实现接口的具体类。然后,您应该能够创建自己的模拟类,并更改代码以使用接口而不是直接使用 System.IO 具体类。

【讨论】:

  • 假设我有一个类对目录中的所有文件执行某些操作。我该如何测试这个?我可以传入一个 DirectoryInfo 对象,但如何模拟它?如何存根它将提供的 FileInfo 对象列表?我如何确保测试实际上不与文件系统交互?
  • 当然,我当然可以创建自己的包装器,但我知道人们已经完成了这项工作,优化了它,发现了错误等等。这是我的问题。
  • @George:你的代码是对目录做些什么,还是对所有文件做些什么?在这种情况下,从可扩展性和可重用性的角度来看,传递 FileInfo 数组或字符串而不是特定目录不是更有意义吗?
【解决方案2】:

我认为您正在寻找this questionthis blog post。 我只包装了 System.IO.File 和 System.IO.Directory。没有 FileInfo 或其他东西。

【讨论】:

  • 谢谢毛里西奥。这不是我正在寻找的内容(我的意思是它不是确切的文章),但我可能最终会使用它,而不是尝试通过 codebetter 挖掘它以找到它。
【解决方案3】:

我很好奇System.IO 命名空间的设计有什么糟糕之处。诚然,选择特定的接口或类可能有点随意,但我不熟悉必须在各处传递字符串的问题。

也许您可以提供有关您的特定问题的更多信息?


编辑

您似乎表明您想要构建在 System.IO 命名空间上的类,这样您就可以在不写入文件系统的情况下进行测试。我没有看到如何充分测试没有它写入文件系统的函数,好吧,写入文件系统。如果你想从写作的角度测试你的逻辑,那么让你的函数采用System.IO.StreamSystem.IO.TextWriter,以更合适的为准。这将允许您测试代码的各个组件,而不必产生任何外部影响;只需传递System.IO.MemoryStream 而不是System.IO.FileStream。显然,您不会遇到空间不足、访问被拒绝等问题,但如果不针对文件系统实时运行,您永远不会遇到这些错误。这就是为什么您可以公开采用 System.IO.FileInfo 或字符串路径(或数组/IEnumerable<>,无论您需要什么)的外部函数,这些函数可以提供另一个实时测试级别。

System.IO 命名空间填充得非常好,而且我从未遇到过使用特别非 OO 的方法。

【讨论】:

  • 我喜欢做 TDD。这意味着我需要的不仅仅是静态类和方法。但就传递字符串而言,请考虑 Directory.GetFiles() ,它将目录作为字符串并将文件作为字符串数组返回。欲了解更多信息,请参阅我对约翰的回应
  • 那为什么不用 DirectoryInfo 和 FileInfo 呢?这两种类型都将 OO 范式带入文件管理。在某些时候,当您谈论路径时,您将不得不处理字符串。我并没有真正看到您链接到的 NDepends 库有任何优势。我错过了你要找的东西吗?
【解决方案4】:

好的,我去挖了。 This 是我指的那篇文章。

this 是 API(源自 ndepend 项目

【讨论】:

    【解决方案5】:

    http://systemwrapper.codeplex.com 提供了一套相当全面的适配器。您会发现几乎所有 System.IO 以及许多其他 System 命名空间都被包装了(如果您正在处理时间敏感的计算,包装 DateTime 类总是一个不错的选择)。

    【讨论】:

      猜你喜欢
      • 2010-12-08
      • 1970-01-01
      • 2010-11-19
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 2021-04-16
      • 2010-09-16
      相关资源
      最近更新 更多