2017-02-23 92 views
2

我想正確使用控制反轉。我的應用程序工作正常。我使用Unity作爲IoC容器。但是,當我選擇使用哪個具體類時,我認爲我錯了。控制反轉和選擇

在這個例子中,我有一個從特定數據源獲取數據的類。根據文件類型,我調用一個數據訪問器類。

這個服務類檢查類型,做一個開關,然後選擇使用哪個具體類。

但是,看起來我在這裏打破了IoC原則,在課堂上「新」了一些東西。我不再注入這個服務類,因爲在這一點上,我還沒有決定使用哪種文件類型。所以我不得不評論'注射',而是硬編碼它。

這是代碼提取。

public class DataService : IDataService 
    { 
     IFileReader _fileReader; 
     public DataService(IFileReader fileReader) 
     { 
      // _fileReader = fileReader; 
     } 

     /// <summary> 
     /// Returns reporting data based on a group of export files. 
     /// </summary> 
     /// <param name="files">A list of files to analyse</param> 
     /// <returns></returns> 
     private List<RawFileData> GetRawData(string[] files) 
     { 
      foreach (var file in files) 
      { 
       // validate files exists. 
       switch (GetFileType(Path.GetFileName(file))) 
       { 
        case "CSV": 
         { 
          fileIsOK = true; 
          _fileReader = new CSVileConnector(); 
          break; 
         } 
        case "TXT": 
         { 
          fileIsOK = true; 
          _fileReader = new TXTFileConnector(); 
          break; 
         } 
        default: 
         break; 
       } 
       if (fileIsOK) 
       { 
        var finedata = _fileReader.ReadData(file); 
        data.Add(new RawFileData 
        { 
         DataItems = finedata, 
         FileName = file 
        }); 
       } 
      } 

      return data; 
     } 

這是處理這種情況的正確方法嗎?在創建類的時候,我不確定哪個孩子類需要「依賴」?然後在邏輯上進行判斷,然後在正確的具體課程中添加新內容?

+0

也許ioc只是原則而非規則。 –

+0

是的,這可能是真的 - 因此我稱之爲原則。但是,如果可以的話,堅持原則往往是件好事。我正在檢查是否正在做的是正確的 - 或者有更好的方法來做到這一點。它可能是 - 不要讓服務層決定數據類型..這應該在數據層完成。在最奇怪的情況下,我的'開關'向下移動一層......而IoC又回到了這裏。但是,我在數據層有同樣的問題。我需要在那裏新建合適的混凝土類。 – Craig

回答

1

一種改進可能是將閱讀器的選擇與閱讀本身分開 - 一種稱爲IFileReader _getDataReader(string filename)的私有方法。所以在你的foreach循環中你說var reader = _getDataReader(filename);。閱讀者沒有理由成爲班上的私人財產,因爲它沒有構建,可以持續改變,其使用範圍限於GetRawData。你在可能考慮注入通過構造函數是一個類GetDataReader(string)在其接口定義。這本身可以容納一個私人的Dictionary<string, Type>這將有其作爲關鍵文件擴展名,然後該文件的讀者作爲值。如果你想要的話,你甚至可以在你的app.config中配置它。這就是所謂的Service Locator模式。

出於各種原因,有很好的論據this is actually an anti-pattern。也許有人會認爲你是在想它 - 因爲你只有兩種選擇,而且這種閱讀方式很容易 - 但是將閱讀者的選擇與閱讀本身分開,至少可以讓你進入一個更容易的地方如果你需要改變。

+1

謝謝乍得。我喜歡_getDataReader位的分離。這使得更多整潔的代碼。我同意'過度思考'和服務定位器。我們團隊的一個要求是不要過度設計它,但要創建易於閱讀和維護的慣用代碼。這個類的構造函數沒有任何注入是可以的?注入現在推遲到文件類型。所以整個反轉控制仍然有效 - 對嗎? – Craig