2012-01-30 23 views
0

私はAutofac DIコンテナを持っており、コンストラクタインジェクションを使ってSampleClassに構成設定を注入します。 Configuration ManagerクラスはsingleInstanceとして作成され、同じ単一インスタンスが使用されます。例外がスローされましたコンストラクタの挿入 - AutoFac Dependency Injection

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'を解決し、それを使用するなどの方法に依存します。非同期、同期、またはマルチスレッドに対処する場合は、一般的なアドバイスを行うことは非常に困難です。 –

答えて

1

あなたは絶対に正しいことをしています。どうして?アプリケーションが正しく構成されていないと、システムの起動が妨げられています。あなたがしたい最後のことは、システムが実際に開始し、後で失敗することです。早く失敗する!ただし、この例外が失われないようにしてください。あなたは、例外がログに記録されることを確認することができます。

ただし、一般的なアドバイスは、型のコンストラクタでできるだけ少なくすることです。入ってくる依存関係をインスタンス変数に格納するだけです。このようにして型の構築は非常に高速で、決して失敗することはありません。一般に、依存関係グラフを構築するのはすばやく、失敗しないようにする必要があります。あなたの場合、システムをできるだけ早く(スタートアップ中に)失敗させたいので、これは本当に問題にはなりません。それでも、一般的なアドバイスを遵守するために、このタイプの外部でこの検証プロセスを抽出することが必要な場合があります。したがって、コンストラクタ内でGetConfigurationSettingsを呼び出す代わりに、コンポジションルート(コンテナを配線するコード)から直接呼び出し、有効なコンフィグレーション設定オブジェクトをConfigurationManagerのコンストラクタに渡します。この方法では、ConfigurationManagerをシンプルにするだけではなく、システムをさらに高速で動作させることができます。

+0

お返事ありがとうございます。私はあなたが "ConfigurationManagerのコンストラクタに有効なコンフィグレーション設定オブジェクトを供給すること"という意味がわかりません。 "ConfigurationManger"は、コンフィグレーション設定を保持し、検証するオブジェクトです.DIコンテナを設定する前に、 。パラメータを検証し、有効である場合はそのインスタンスをDIコンテナに供給します。更新されたメインの答えを見る – ministrymason

-1

私は良い練習組成時に例外をスロー呼び出すことはありません。これは、構成がかなり複雑で間接的な実行ロジックを持つため、合理的な例外処理を事実上不可能にする可能性があるからです。私はあなたがより良いものを発明することができ疑うひどい

try 
{ 
    var someComponent = context.Resolve<SampleClass>(); 
} 
catch 
{ 
    // Yeah, just stub all exceptions cause you have no idea of what to expect 
} 
私は、彼らが本当に(それが何をする必要がありますしない限り、彼らのコンストラクタが例外をスローしないような方法で自分のクラスを再設計をお勧めしたい

例えば彼らが持つ絶対に役に立たない場合null値のコンストラクタパラメータ)。その後、あなたのアプリを初期化し、エラーを処理し、おそらくそれを行うためにユーザーと対話するいくつかのメソッドが必要になります。

0

コアの問題は、合成中にいくつかの実行を実行して、オブジェクトグラフの合成と実行を混在させることです。 DIスタイルでは、コンストラクタはできるだけシンプルにする必要があります。 GetConfigurationSettingsメソッドが呼び出されたときなど、クラスが意味のある作業を実行するように求められたら、それが本格的に始めるべきです。

このように物を構造化することの主な利点は、すべてをより予測可能にすることです。構成中のエラー実際にの構成エラーです。実行中のエラーは実際にはです。実行エラーはです。

作業のタイミングも予測可能です。私は、アプリケーションの構成は実際には実行時に変更されないことに気が付いていますが、ファイルを読み込むクラスがあったとしましょう。コンポジション中にコンストラクタでそれを読み取ると、ファイルの内容は、実行中にそのデータを使用するときに変わる可能性があります。ただし、実行中にファイルを読み込むと、そのようなキャッシングの形で必然的に発生するタイミングの問題を避けることができます。

キャッシュがアルゴリズムの一部である場合、それはGetConfigurationSettingsのためであると想像しているように、それは構成ではなく実行の一部として実装するのが理にかなっています。キャッシュされた値は、ConfigurationManagerインスタンスと同じ存続期間を持つことはできません。たとえそれがコンストラクタにエンコードされていても、1つのオプションしか残されません。実行時キャッシュがより柔軟性を提供するように、は例外の抱える問題を解決します。

関連する問題