我創建一個CSV閱讀器(是的,我知道快速CSV閱讀器和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時常見的問題。什麼是這個好的解決方案?
我同意這一點,但我不希望圖書館的消費者在創建閱讀器時不得不創建解析器。是否最好有另一個構造函數,我只是通過路徑,它創建解析器並使用給定的路徑?或者使用一個接受文件路徑的工廠會更好,並創建閱讀器和解析器並返回閱讀器? –
如果你不想用戶必須創建一個解析器,那麼是的,你最好的選擇是有一個工廠,它會吃掉路徑並返回一個構造的'ICsvReader'。正如我所描述的,您仍然應該設置'CsvParser'和'CsvReader'。我說構造函數裏面的'new'是一個小的。第二種氣味是構造函數中的對象圖構造。也就是說,'CsvReader'的構造函數不應該接受其他對象的依賴('CsvParser')並使用它來構造它自己。該工作應委派給工廠。 SRP和所有這一切。 – jason
太好了。我原來是這樣設置的,但我不喜歡要求解析器傳遞到構造函數中才能正常使用。我只是使用工廠進行簡單/默認創建,一切都應該很好。 –