Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 只执行第一次实例化_C#_.net - Fatal编程技术网

C# 只执行第一次实例化

C# 只执行第一次实例化,c#,.net,C#,.net,也许这是不可能的,但我想验证一下 我有一个类,在它的构造函数中,它从Windows注册表中读取一些值 我需要在类内读取该值,但无法将其作为参数传递给类 这是类(DBContext,读取的值是连接字符串) 公共类VtulDb:IdentityDbContext { 公共VtulDb() { RegistryKey hklm=RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,RegistryView.Registry64); RegistryKey

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

我有一个类,在它的构造函数中,它从Windows注册表中读取一些值

我需要在类内读取该值,但无法将其作为参数传递给类

这是类(DBContext,读取的值是连接字符串)

公共类VtulDb:IdentityDbContext
{
公共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;
}
公共数据库集计算机{get;set;}
}
所以,问题是这个类在每个请求中都是从一个web站点实例化的。因此,在每个请求中,应用程序都在读取注册表项,我认为这不是最好的方法

要在类第一次实例化时从注册表中读取该值,然后将该字符串放入RAM中,您会怎么做?

我会定义一个“惰性”静态属性(仅在首次访问该属性后才计算其值的属性):


然后,任何实例都可以随时访问
属性,而不是计算它。

最初,我被延迟加载蒙蔽了双眼,但我会使用,因为它保证只运行一次

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的方法和实际对象来保证线程安全,并封装行为

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; }
}
私有静态只读延迟连接\u字符串=
新懒惰(()=>
{
//此代码仅在首次使用时调用
注册密钥hklm=
RegistryKey.OpenBaseKey(
RegistryHive.LocalMachine、RegistryView.Registry64);
RegistryKey branch=hklm.OpenSubKey(@“SOFTWARE\Tulpep\Vtul”);
返回branch.GetValue(“DBConnectionString”).ToString();
});
私有静态字符串连接字符串
{
获取{返回连接_STRING.Value;}
}

没有同步的延迟加载不是线程安全的,而且对于一些可能并行使用的代码,这可能是不明智的。幸运的是,从完全相同的源加载相同的键不太可能导致任何问题,但原则是正确的。

为什么不能将此值传递给类?如果可以,可以将其存储为会话变量。(你可以这样做,但那会很麻烦)研究缓存,这将是解决这个问题的一个解决方案。如果你真的不能通过参数传递值,静态构造函数也可能会派上用场。我不想传递参数,因为这个类被多个项目(web应用程序、windows服务等)使用;所以我不想在多个地方阅读(不要重复我自己)。这很有魅力。使用process monitor,我检查了对注册表项的访问,并且它只是第一次被访问!!!你为什么说它懒惰?在这种情况下使用的是dev术语吗?
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();
    }
}
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; }
}