c# - 如何注入(inject)表示文件夹集合的依赖项?

标签 c# testing dependency-injection dependencies software-design

依赖注入(inject)文件夹的最佳方式是什么?

我有一个类需要三个文件夹。目标是从子文件夹结构(一个包含多个文件夹的文件夹,文件被分类到其中)收集文件并将其写入另外两个子文件夹结构,无论是否通过抽象,它都需要文件夹。

具体来说,我想将机器学习算法的数据拆分为 training and test data而子文件夹代表将要分类的图像的不同类别。

那么,注入(inject)这些文件夹的最佳方式是什么,同时仍然具有易于测试的代码? 我应该只传递一个字符串吗?我应该传递一个 FileInfo 对象吗?我应该构建一个接口(interface),它代表文件夹结构的包装器吗? 处理此问题的最佳方法是什么?

C# 方法是最好的,但不是必需的。

如果缺少信息,请告诉我。

最佳答案

现在使用 System.IO.Abstractions 表示文件系统操作而不实际依赖于文件系统更容易.该模式类似于我们如何编写依赖于 HttpContextWrapper 的代码。而不是直接在 HttpContext 上,这让我们可以模拟 HttpContext .

使用这些类你可以注入(inject) IEnumerable<System.IO.Abstractions.DirectoryInfoWrapper> ,并且在运行时每个目录都是一个“真实的”DirectoryInfo , 像这样创建:

var directory = new DirectoryInfo("c:\folder");
var wrapper = new DirectoryInfoWrapper(new FileSystem(), directory);

DirectoryInfoWrapper行为就像 DirectoryInfo除了它还返回抽象。例如,wrapper.GetFiles()返回 IFileInfo[]而不是 FileInfo[] .因此,我们所有的代码都将编写为依赖于抽象。这很好,因为抽象具有与具体类相同的属性和方法。

或者,您可能需要这样的东西,而不是注入(inject)实际的目录:

public interface IDirectoryProvider
{
    IEnumerable<DirectoryInfoWrapper> GetDirectories(string someInput);
}

在任何一种情况下,这都允许您使用模拟目录进行单元测试,如有必要,模拟目录包含更多模拟目录甚至模拟文件。我通常不喜欢返回模拟的模拟。如果这比创建模拟文件更容易,您甚至可以让模拟目录返回包含在测试项目中的真实文件。至少它提供了一些在抽象之前不可用的选项。


令人毛骨悚然的细节:有人可能会争辩说这些并不是真正的“抽象”,因为根据设计,它们是具体类的精确表示。您可以使用它们来表示完全不同的东西,例如数据库存储,但您可能不会,它们也不是很好的抽象,因为它会迫使您将虚假路径映射到记录。

话虽这么说,但我试着想象我会把命名空间称为什么而不是 System.IO.Abstractions我想不出更好的了。您可以称它们为“模拟”,但在生产代码中看到它们会让人感到困惑。

关于c# - 如何注入(inject)表示文件夹集合的依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48330707/

相关文章:

Perl - TAP::Harness 和 test_args

android - 将测试类/包放在一个测试套件中

google-app-engine - 带有 Google Cloud Endpoints 和 Guice 的 Appengine

java - 让测试通过一组 JMock 的模拟方法调用

java - 如何在非托管实例中 Autowiring 类?

java - 为什么来自 TestNG 交付的 Guice 不能识别 @javax.inject.Inject 而来自 com.google.inject 包的 Guice 可以?

c# - 单线程应用程序是否只在一个 CPU 上运行

c# - 返回该方法接受的相同对象有什么问题吗?

c# - Server.Transfer 到 HttpHandler

c# - 在范围末尾执行清理的结构是一个好的 C# 模式吗?