第一次执行instanced

时间:2014-01-19 00:34:53

标签: c# .net

也许这是不可能的,但我想验证。

我有一个类,在它的构造函数中,它从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中?

2 个答案:

答案 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; }
}

没有同步的延迟加载不是线程安全的,并且某些代码似乎可能并行使用,这可能是不明智的。幸运的是,从完全相同的源加载相同的密钥不太可能导致任何问题,但原则就是这样。