【问题标题】:Initializing properties of static class fails with null value exception初始化静态类的属性失败,出现空值异常
【发布时间】:2019-12-18 00:44:29
【问题描述】:

我有一个静态连接工厂类,需要从配置中初始化连接参数

namespace MyApp.Common.LinqToDB
{
    public static class MyConnectionFactory
    {
        public static string Authority { get; set; }
        public static string Target { get; set; }
        public static string ConnectionString { get; set; }
        public static string ClientId { get; set; }
        public static string ClientSecret { get; set; }
        private static ClientCredential ClientCredential = new ClientCredential(ClientId, ClientSecret);

    public static IDbConnection createConnection()
        {
            AuthenticationContext authenticationContext = new AuthenticationContext(Authority);
            AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(Target, ClientCredential).Result;
            SqlConnection MyDataConnection = new SqlConnection(ConnectionString);
            MyDataConnection.AccessToken = authenticationResult.AccessToken;

            return MyDataConnection;
        }
    }
}

我尝试从主 parogram 初始化这些属性

MyConnectionFactory.Authority = "blahblah";

这会在静态类中引发空值异常。该值没有到达类。

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'Workspace.Common.LinqToDB.WorkspaceConnectionFactory' threw an exception.
  Source=Common
  StackTrace:
   at Workspace.Common.LinqToDB.WorkspaceConnectionFactory.set_Authority(String value) in 

........
Inner Exception 1:
ArgumentNullException: Value cannot be null.
Parameter name: clientId

设置静态类的静态属性值是不是错了。 我知道静态构造函数(),但它不带参数,我需要设置连接参数。 静态工厂不是连接工厂的正确模式。如果我不让工厂静态化,我可以让这一切正常工作,但这似乎不是正确的做法。

【问题讨论】:

    标签: c# initialization static-classes


    【解决方案1】:

    private static ClientCredential ClientCredential = new ClientCredential(ClientId, ClientSecret); 将被编译为:

    private static ClientCredential ClientCredential;
    
    //Static constructor
    static MyConnectionFactory()
    {
      ClientCredential = new ClientCredential(ClientId, ClientSecret);
    }
    

    静态构造函数用于初始化任何静态数据,或执行只需要执行一次的特定操作。在创建第一个实例或引用任何静态成员之前自动调用它。
    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

    现在,当您尝试分配Authority 时,必须先调用静态构造函数。此时,ClientIdClientSecret 仍然为空,导致异常。

    【讨论】:

    • 当您尝试设置它时,必须先调用构造函数,因为它是静态的。 ClientId此时仍为null,所以new ClientCredential(ClientId, ClientSecret);会抛出异常
    • 抱歉,异常不在new AuthenticationContext(Authority);,而是在属性设置器中。我无法理解随时设置静态类的静态属性有什么问题。
    • 我编辑了答案,请检查它,因为它希望更清楚
    • 明白。所以指向Authority属性的set方法的空值异常其实是由于静态ClientCredential调用造成的。感谢您的洞察力。我永远也猜不到。我把它移到那里作为优化。它最初在 createConnection() 中。把它移回那里解决了这个问题。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多