データベース接続を作成するために使用される小さなルーチンを使用していました。
前
public DbConnection GetConnection(String connectionName)
{
ConnectionStringSettings cs= ConfigurationManager.ConnectionStrings[connectionName];
DbProviderFactory factory = DbProviderFactories.GetFactory(cs.ProviderName);
DbConnection conn = factory.CreateConnection();
conn.ConnectionString = cs.ConnectionString;
conn.Open();
return conn;
}
次に、.NET フレームワークのドキュメントを調べて、ドキュメントに記載されているさまざまな動作がどのようなものかを確認し、それらを処理できるかどうかを確認しました。
例えば:
ConfigurationManager.ConnectionStrings...
ドキュメントには、コレクションを取得できなかった場合にConnectionStringsを呼び出すとConfigurationErrorExceptionがスローされることが記載されています。この場合、この例外を処理するためにできることは何もないので、手放します。
次の部分は、 connectionNameを見つけるためのConnectionStringsの実際のインデックス付けです。
...ConnectionStrings[connectionName];
この場合、ConnectionStrings のドキュメントには、接続名が見つからない場合、プロパティはnullを返すと記載されています。私はこれが起こっていることを確認し、例外をスローして、無効な接続名を与えたことを誰かに知らせることができます:
ConnectionStringSettings cs=
ConfigurationManager.ConnectionStrings[connectionName];
if (cs == null)
throw new ArgumentException("Could not find connection string \""+connectionName+"\"");
私は同じ演習を繰り返します:
DbProviderFactory factory =
DbProviderFactories.GetFactory(cs.ProviderName);
GetFactoryProviderName
メソッドには、指定されたのファクトリが見つからなかった場合に何が起こるかについてのドキュメントがありません。を返すようnull
に文書化されていませんが、私はまだ防御的で、nullをチェックすることができます:
DbProviderFactory factory =
DbProviderFactories.GetFactory(cs.ProviderName);
if (factory == null)
throw new Exception("Could not obtain factory for provider \""+cs.ProviderName+"\"");
次は、DbConnection オブジェクトの構築です。
DbConnection conn = factory.CreateConnection()
繰り返しますが、ドキュメントには、接続を作成できなかった場合に何が起こるかは記載されていませんが、null の戻りオブジェクトを確認できます。
DbConnection conn = factory.CreateConnection()
if (conn == null)
throw new Exception.Create("Connection factory did not return a connection object");
次に、Connection オブジェクトのプロパティを設定します。
conn.ConnectionString = cs.ConnectionString;
ドキュメントには、接続文字列を設定できなかった場合にどうなるかは記載されていません。例外をスローしますか?それは無視しますか?ほとんどの例外と同様に、接続の ConnectionString を設定しようとしたときにエラーが発生した場合、そこから回復するためにできることは何もありません。だから私は何もしません。
最後に、データベース接続を開きます。
conn.Open();
DbConnectionのOpen メソッドは抽象的であるため、どのプロバイダーがスローする例外を決定するかは、DbConnection から派生しているプロバイダー次第です。エラーが発生した場合に何が起こるかについて、抽象 Open メソッドのドキュメントにもガイダンスはありません。接続中にエラーが発生した場合、それを処理できないことはわかっています。発信者がユーザーに UI を表示できる場所でバブルを発生させ、再試行させる必要があります。
後
public DbConnection GetConnection(String connectionName)
{
//Get the connection string info from web.config
ConnectionStringSettings cs= ConfigurationManager.ConnectionStrings[connectionName];
//documented to return null if it couldn't be found
if (cs == null)
throw new ArgumentException("Could not find connection string \""+connectionName+"\"");
//Get the factory for the given provider (e.g. "System.Data.SqlClient")
DbProviderFactory factory = DbProviderFactories.GetFactory(cs.ProviderName);
//Undefined behaviour if GetFactory couldn't find a provider.
//Defensive test for null factory anyway
if (factory == null)
throw new Exception("Could not obtain factory for provider \""+cs.ProviderName+"\"");
//Have the factory give us the right connection object
DbConnection conn = factory.CreateConnection();
//Undefined behaviour if CreateConnection failed
//Defensive test for null connection anyway
if (conn == null)
throw new Exception("Could not obtain connection from factory");
//Knowing the connection string, open the connection
conn.ConnectionString = cs.ConnectionString;
conn.Open()
return conn;
}
概要
したがって、私の 4 行の関数は 12 行になり、5 分間のドキュメント検索が必要になりました。最後に、メソッドが null を返すことが許可されている 1 つのケースをキャッチしました。しかし、実際には、アクセス違反の例外 (null 参照でメソッドを呼び出そうとした場合) をInvalidArgumentExceptionに変換するだけでした。
また、 nullの戻りオブジェクトが存在する可能性のある 2 つのケースもキャッチします。しかし、繰り返しになりますが、1 つの例外を別の例外と交換しただけです。
良い面としては、2 つの問題を検出し、例外メッセージで何が起こったのかを説明した方が、後で悪いことが起こった (つまり、ここでお金が止まった) ということではありませんでした。
しかし、それは価値がありますか?これはやり過ぎですか?この防御的なプログラミングはうまくいかないのでしょうか?