2014-01-19 109 views
1

也許這是不可能的,但我想驗證。執行第一次實例

我有一個類,並在其構造函數中從Windows註冊表中讀取一些值。

我需要這個價值在班級裏面,我不能把它作爲參數傳遞給班級。

這是類(A的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

準確地說,你爲什麼不能把這個值傳遞給你的班級?如果可以的話,可以將它作爲會話變量存儲。 (你可以反正,但那會很混亂) – 2014-01-19 00:37:33

+0

研究緩存這將是解決這個問題的方法。 –

+0

靜態構造函數也可能派上用場,如果你真的不能通過參數傳遞值。 – Patko

回答

2

我會定義一個「懶惰」的靜態屬性(一個計算其價值後,才第一次被訪問):

private static RegistryKey _key; 
private static RegistryKey Key { 
    get { 
     if (_key == null) { 
      // calculate the value and set _key here 
     } 
     return _key; 
    } 
} 

任何實例可以在任何時間訪問Key屬性,而不是計算它的。

+0

工程就像一個魅力。使用進程監視器我檢查了對註冊表項的訪問權限,並且它僅被第一次訪問! –

+0

你爲什麼稱它爲懶惰?這是在這種情況下使用的開發術語嗎? –

+0

@RicardoPolo http://en.wikipedia.org/wiki/Lazy_evaluation – nmclean

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

不同步延遲加載不是線程安全的,並與一些代碼,很可能在並行使用,也可以是不明智的。幸運的是,從完全相同的來源加載相同的密鑰不太可能導致任何問題,但是原理是成立的。

相關問題