创建使用控制反转的对象

Jos*_*ose 2 c# dependency-injection inversion-of-control

我正在创建一个CSV阅读器(是的,我知道Fast CSV Reader和FileHelpers).CsvReader类使用CsvParser类来解析CSV文件.我想使CsvReader类单元可测试,所以我希望能够在外部设置所使用的CsvParser类(同样,您也可以创建自己的实现).我也不想创建一个解析器并在正常使用时传递它.

这就是我想用它的方式.

var reader = new CsvReader( "path/to/file.csv" );
Run Code Online (Sandbox Code Playgroud)

执行此操作时,我可以在CsvReader的构造函数中创建CsvParser,并具有更改解析器的属性.

public ICsvParser Parser { get; set; }

public CsvReader( filePath )
{
    Parser = new CsvParser( filepath );
}
Run Code Online (Sandbox Code Playgroud)

但是在单元测试时,总是创建默认解析器,我只想测试CsvReader.

解析器可以传递给构造函数,但我不想在正常使用时单独创建解析器.这似乎是一个工厂的好地方.

这似乎是使用IOC时的常见问题.对此有什么好的解决方案?

jas*_*son 5

解决方案是重写你的构造函数CsvReader来接受一个实现,ICsvParser并且你的具体实现ICsvParser应该有一个构造函数接受它的依赖项(一个文件的路径来解析),并且已经构造的ICsvParser应该被注入到构造函数中CsvReader:

public CsvReader(ICsvParser parser) {
    this.Parser = parser;
}
Run Code Online (Sandbox Code Playgroud)

ICsvParser应该已经被构建为接受它的依赖(该文件的路径被解析).

正是如此:

// path is string containing path to file to parse
ICsvParser parser = new SomeCsvParser(path);
ICsvReader reader = new CsvReader(parser);
Run Code Online (Sandbox Code Playgroud)

关键是CsvReader不需要路径,只需要一个CsvParser.此外,CsvReader不需要知道CsvParser(它需要一个文件的路径来解析)的依赖性,以免它依赖于这些依赖性.

new 构造函数内部是一种气味.