2012-01-30 149 views
0

我有一個Autofac DI容器,並使用構造函數注入將配置設置注入到我的SampleClass中。配置管理器類創建爲singleInstance,因此使用相同的單個實例。拋出異常構造函數注入 - AutoFac依賴注入

public ConfigurationManager() 
{ 
    // Load the configuration settings 
    GetConfigurationSettings(); 
} 

public SampleClass(IConfigurationManager configurationManager) 
{ 
    _configurationManager = configurationManager; 
} 

我從配置管理器的構造函數中的App.config文件加載配置設置。我的問題是我也驗證配置設置,如果他們不在App.config文件中引發異常,這會導致程序崩潰。這意味着我無法處理異常並返回響應。

我這樣做是錯誤的嗎?是否有更好的方法來加載配置設置還是有辦法處理拋出的異常。

編輯

ConfigurationManager configurationManager = new ConfigurationManager(); 
configurationManager.GetConfigurationSettings(); 
//Try catch around for the exception thrown if config settings fail 

//Register the instance above with autofac 
builder.Register(configurationManager()).As<IConfigurationManager>().SingleInstance(); 


//Old way of registering the configurationManager 
builder.Register(c => new ConfigurationManager()).As<IConfigurationManager>().SingleInstance(); 
+0

這是太少的細節。解決方案取決於你初始化容器的方式,解決'SampleClass',使用它等等。如果你處理異步,同步或多線程,很難給出一個通用的建議。 – 2012-01-30 17:20:57

回答

1

你正在做的絕對是正確的事情。爲什麼?當應用程序配置不正確時,您正在阻止系統啓動。你想要發生的最後一件事是系統實際啓動並在以後失敗。快速失敗!但是,請確保此異常不會丟失。您可以確保記錄異常。

雖然有一點需要注意。一般的建議是在類型的構造函數中儘可能少地執行。只需將實例變量中傳入的依賴項存儲就可以了。這種構建方式非常快速,永遠不會真正失敗。一般來說,構建依賴關係圖應該很快,不應該失敗。在你的情況下,這不會是一個問題,因爲你希望系統儘快失敗(在啓動過程中)。儘管如此,爲了遵守一般建議,您可能希望在該類型之外提取此驗證過程。因此,不要在該構造函數中調用GetConfigurationSettings,而是從組合根(編寫容器的代碼)直接調用它,並將有效的配置設置對象提供給ConfigurationManager的構造函數。通過這種方式,您不僅可以簡化ConfigurationManager,還可以讓系統更快地失敗。

+0

感謝您的迴應。我不確定你的意思是什麼「爲ConfigurationManager的構造函數提供有效的配置設置對象」ConfigurationManger只是一個保存和驗證配置設置的對象。您是否意味着在設置DI容器之前創建一個配置管理器的實例。驗證參數,如果它們有效,則將該實例提供給DI容器。查看更新的主要答案 – ministrymason 2012-01-31 09:50:11

-1

我不會把在組成時拋出異常一個很好的做法。這是因爲組合可能具有相當複雜和間接的執行邏輯,使合理的異常處理幾乎不可能。我懷疑你會發明什麼優於可怕

try 
{ 
    var someComponent = context.Resolve<SampleClass>(); 
} 
catch 
{ 
    // Yeah, just stub all exceptions cause you have no idea of what to expect 
} 

我建議的方式,除非他們真的需要做的(它們的構造函數不拋出異常,重新設計類例如,如果它們與絕對沒用一個空值構造函數參數)。然後,您需要一些方法來初始化您的應用程序,處理錯誤並可能與用戶交互來完成此操作。

0

核心問題是,您在構圖過程中通過執行一些執行來混合對象圖的組合和執行。在DI風格中,構造函數應儘可能簡單。當你的班級被要求執行一些有意義的工作時,例如當調用GetConfigurationSettings方法時,這是你認真開始的信號。

以這種方式構造事物的主要好處是它使一切都變得更加可預測。構圖期間出現錯誤構圖錯誤,並且執行期間錯誤確實執行錯誤。

工作時間也更可預測。我意識到應用程序配置在運行時並不真正改變,但假設你有一個讀取文件的類。如果您在構圖過程中在構造函數中讀取它,則在執行期間您使用該數據時,文件的內容可能會發生變化。但是,如果您在執行過程中閱讀文件,則可以避免這種形式的緩存不可避免地出現的時間問題。

如果緩存是算法的一部分,就像我想象的那樣是GetConfigurationSettings,那麼將它作爲執行的一部分而不是組合實現仍然有意義。緩存的值可能與ConfigurationManager實例的壽命不同。即使他們這樣做了,編碼到構造函數中也只剩下一個選項,其中執行時緩存提供了更大的靈活性它解決了您的異常問題。