也许这是不可能的,但我想验证。
我有一个类,在它的构造函数中,它从Windows注册表中读取一些值。
我需要将这个值重写为类,我不能将它作为参数传递给类。
这是类(DBContext和值readed是连接字符串)
public class VtulDb : IdentityDbContext<User>
{
public VtulDb()
{
RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey vtulRegistryBranch = hklm.OpenSubKey(@"SOFTWARE\Tulpep\Vtul");
string connectionString = vtulRegistryBranch.GetValue("DBConnectionString").ToString();
Database.Connection.ConnectionString = connectionString;
}
public DbSet<Computer> Computers { get; set; }
}
所以,问题是这个类是在每个请求中从一个网站实现的。所以在每个请求中,应用程序都在读取注册表项,我不认为这是最好的方法。
在第一次实例化类时,你会如何从注册表中读取这个值,然后将字符串放在RAM中?
答案 0 :(得分:2)
我会定义一个“懒惰”静态属性(仅在首次访问后才计算其值):
private static RegistryKey _key;
private static RegistryKey Key {
get {
if (_key == null) {
// calculate the value and set _key here
}
return _key;
}
}
然后,任何实例都可以随时访问Key
属性,而不是计算它。
答案 1 :(得分:1)
最初,我对延迟加载有点盲目,但我会使用static
constructor,因为它只保证运行一次。
class VtulDb
{
private static readonly string CONNECTION_STRING;
static VtulDb
{
// this code is only invoked on first use
RegistryKey hklm =
RegistryKey.OpenBaseKey(
RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey branch = hklm.OpenSubKey(@"SOFTWARE\Tulpep\Vtul");
// store string
CONNECTION_STRING = branch.GetValue("DBConnectionString").ToString();
}
}
这样可以避免同步,同时仍然提供线程安全的单个延迟调用。
如果你想懒惰地初始化它,那么我会使用nmclean的方法和一个实际的Lazy
对象来保证线程的安全性,以及封装行为。
private static readonly Lazy<string> CONNECTION_STRING =
new Lazy<string>(() =>
{
// this code is only invoked on first use
RegistryKey hklm =
RegistryKey.OpenBaseKey(
RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey branch = hklm.OpenSubKey(@"SOFTWARE\Tulpep\Vtul");
return branch.GetValue("DBConnectionString").ToString();
});
private static string ConnectionString
{
get { return CONNECTION_STRING.Value; }
}
没有同步的延迟加载不是线程安全的,并且某些代码似乎可能并行使用,这可能是不明智的。幸运的是,从完全相同的源加载相同的密钥不太可能导致任何问题,但原则就是这样。