すべてのユーザー アクセス設定の読み取りを担当する 1 つのオブジェクトを作成しようとしています。
私はクラスを次のように作成しました:
public class SettingsManager
{
private static string _connString =
@"Data Source=MyDB;Initial Catalog=IT;Integrated Security=True;Asynchronous Processing=true;";
private const string _spName = "SettingTest";
private IEnumerable<string> _mySettings;
private static readonly Lazy<SettingsManager> _instance = new Lazy<SettingsManager>(() => new SettingsManager());
private SettingsManager()
{
//Console.WriteLine("Hello from constructor");
if (_mySettings == null)
_mySettings = ReadSettings();
}
public static SettingsManager Instance
{
get { return _instance.Value; }
}
public bool CanDo(string setting)
{
return _mySettings.Contains(setting);
}
private IEnumerable<string> ReadSettings()
{
try
{
using (var conn = new SqlConnection(_connString))
{
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = _spName;
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
using (var reader = cmd.ExecuteReader())
{
return reader.Select(SettingParser).ToList();
}
}
}
}
catch
{
}
return null;
}
private string SettingParser(SqlDataReader r)
{
try
{
return r[0] is DBNull ? null : r[0].ToString();
}
catch
{
}
return null;
}
}
および SqlDataReader 拡張機能
public static class DBExtensions
{
public static IEnumerable<T> Select<T>(
this SqlDataReader reader, Func<SqlDataReader, T> projection)
{
while (reader.Read())
{
yield return projection(reader);
}
}
}
次に、アプリケーション内で次のように呼び出すことができます。
SettingsManager.Instance.CanDo("canWrite")
これは、ユーザーのアクセス レベルに応じて true/false 値を返します。
私の質問は次のとおりです。
このスレッドは安全ですか? DBが複数回クエリされる可能性はありますか? これを防ぐ方法は?
await と async を使用する必要がありますか? db を一度だけクエリします。どうすればこれを改善できますか? (.NET3.5 から 4.5 に移行したばかりなので、await と async は私にとってまったく新しいものです)