tags:

views:

134

answers:

2

Recently I have observed the following interesting scenario in one of the application I'm developing using .NET 3.5. In this particualr application I have a singletion object which I access as a static variable. I exepected that the .NET run time should initializes this singleton object at the very first time I access it, but it seems this is not the case. .NET runtime initialize it way before I access this particualr object. Following is some peudo code,

if(!initSingleton)
   //Do some work without using the singletion class.
else
   //Do some work using the singletion class.

Even at runtime my code only executes the code in side the if statement .NET runtime still initializes the singleton object. In some of the application runs I don't need to access this pariticualr object at all!

Also I don't see this behavior with debug builds. Seems this has something to do with optimized builds (release builds).

Is this is the expected behavior of the .NET runtime?

Update:

Following is the actual code,

private void InitServiceClient(NetworkCredential credentials, bool https)
        {
            string uri = currentCrawlingWebUrl;
            if (!uri.EndsWith("/"))
                uri = string.Concat(uri, "/");
            uri = string.Concat(uri, siteDataEndPointSuffix);

            siteDataService = new SiteData.SiteDataSoapClient();
            siteDataService.Endpoint.Address = new EndpointAddress(uri);

            if (credentials != null)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential = credentials;
            }
            else if (MOSSStateHandler.Instance.UserName.Length > 0 && MOSSStateHandler.Instance.Password.Length > 0)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential.UserName = MOSSStateHandler.Instance.UserName;
                siteDataService.ClientCredentials.Windows.ClientCredential.Password = MOSSStateHandler.Instance.Password;
                siteDataService.ClientCredentials.Windows.ClientCredential.Domain = MOSSStateHandler.Instance.Domain;
            }

            BasicHttpBinding httpBinding = (BasicHttpBinding)siteDataService.Endpoint.Binding;
            httpBinding.Security.Mode = (https ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);

            string authmode = MOSSConnectorConfiguration.Instance.Config.GetString(ConfigConstants.SHAREPOINT_AUTH_PROVIDER, "ntlm");
            if (authmode.Equals("ntlm", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
            else if (authmode.Equals("kerberos", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            else
                throw new Exception(string.Format("Not supported"));
        }

Even though my application doesn't execute the code in side else if block the class MOSSStateHandler get initialized.

+2  A: 

From C# language spec:

The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.
notnoop
Yes... however in the above code I neither do creation nor referencing. In other words code inside my else block never get executed.
Shamika
@Shamika, you need to show more code for us to help. how is iniSingleton initialized?
notnoop
I have added some sample code.
Shamika
+3  A: 

I suggest you read Jon Skeet's article about Singleton pattern in C#, and its appendix about lazy-loading etc. You'll get better understanding about the implementation issues.

Ron Klein
Indeed, if the OP's class doesn't have a static constructor then it'll be marked as `beforefieldinit` by the compiler and the type initialisation can occur at any time (prior to any access of the static fields, of course).
LukeH
I have implemented my singleton class as "Fourth version - not quite as lazy, but thread-safe without using locks". I'm still confused with the behavior I see in my app though.
Shamika
@Shamika: If your singleton is implemented as the fourth version from Jon's article then you shouldn't be seeing the behaviour you describe in the question.
LukeH
Yes, I’m also confused about this particular behavior. Especially why I don’t see this in debug builds. I’m suspecting this has something do with optimized code generated by the c# compiler.
Shamika