我正在创建一个 CSV 阅读器(是的,我知道 Fast CSV Reader 和 FileHelpers)。 CsvReader 类使用 CsvParser 类来解析 CSV 文件。我想让 CsvReader 类可以进行单元测试,所以我希望能够在外部设置使用的 CsvParser 类(同时,这样您就可以创建自己的实现)。我也不想创建解析器并在正常使用时将其传递。
这就是我想使用它的方式。
var reader = new CsvReader( "path/to/file.csv" );
执行此操作时,我可以在 CsvReader 的构造函数中创建 CsvParser 并具有更改解析器的属性。
public ICsvParser Parser { get; set; }
public CsvReader( filePath )
{
Parser = new CsvParser( filepath );
}
但是当单元测试时,默认解析器总是被创建,我只想测试 CsvReader。
解析器可以传递到构造函数中,但我不想在正常使用时单独创建解析器。这似乎是建工厂的好地方。
这似乎是使用 IOC 时的常见问题。对此有什么好的解决方案?
最佳答案
解决方案是重写 CsvReader
的构造函数以接受 ICsvParser
的实现,并且 ICsvParser
的具体实现应该有一个构造函数采用在其依赖项中(要解析的文件的路径)和一个已经构建的 ICsvParser
应该被注入(inject)到 CsvReader
的构造函数中:
public CsvReader(ICsvParser parser) {
this.Parser = parser;
}
ICsvParser
应该已经构造为接受它的依赖项(要解析的文件的路径)。
因此:
// path is string containing path to file to parse
ICsvParser parser = new SomeCsvParser(path);
ICsvReader reader = new CsvReader(parser);
重点是CsvReader
不需要路径,它只需要一个CsvParser
。此外,CsvReader
不需要知道 CsvParser
的依赖项(它需要一个文件路径来解析),以免它也依赖于这些依赖项。
new
构造函数内部有一股味道。
关于c# - 创建使用控制反转的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1975304/