LeopardSkinPillBoxHat
LeopardSkinPillBoxHat

Reputation: 29421

Type initializer threw exception while accessing static property

I have the following static property defined:

namespace Foo
{
    public class Bar
    {
        private static byte[] aes256Key = null;
        internal static byte[] Aes256Key
        {
            get
            {
                if (aes256Key != null)
                {
                    return aes256Key;
                }

                aes256Key = new byte[32];

                // Fill in key...

                return aes256Key;
            }
        }
    }
}

In another class within an internal namespace, I am accessing this property:

namespace Foo.Cryptography
{
    public class SymmetricCryptography
    {
        internal static void EncryptFile(
            string sourceFile,
            string destinationFile)
        {
            // <snip>
            AesManaged aes = new AesManaged();
            aes.BlockSize = 128;
            aes.KeySize = 256;
            aes.Key = Bar.Aes256Key; // Accessing the key here
            // <snip>
        }
    }
}

Foo.Cryptography is used by an executable console application. When I run this console application manually from my build environment, I don't see any issues. However, when the executable is run within the context of the build process (on a server with a potentially different environment), I see the following runtime exception:

The type initializer for 'Foo.Bar' threw an exception.

The executable project in VS2008 has a reference to the Foo project which defines the Foo namespace.

Am I doing anything fundamentally wrong here? What could be causing this?

Upvotes: 1

Views: 1829

Answers (3)

s_nair
s_nair

Reputation: 812

It's really hard to work on 'static world' without seeing the complete code. Nonetheless, following are few area that you can work on (personally) in order to find the cause.

aes256Key = new byte[32];
// Fill in key...
return aes256Key;
  1. It's reasonable to check the possible exception in your 'Fill in key' logic

  2. Define a static constructor for this Bar and initialize all your static fields.

  3. Ensure you call following RuntimeHelpers.RunClassConstructor(typeof(Bar).TypeHandle) before even accessing any static/instance field/member/method.

    static void Main(string[] args)

    {

    RuntimeHelpers.RunClassConstructor(typeof(Bar).TypeHandle);
    byte[] bt = Bar.Aes256Key;
    

    }

RuntimeHelpers.RunClassConstructor does ask the runtime to call the static constructor regardless of the reasons specified in the CLI. This ensure deterministic unit initialization order. This is necessary because type initializer believe in Lazy initialization.

Upvotes: 1

Brandon Moore
Brandon Moore

Reputation: 8780

Are Foo.Cryptography and Foo.Bar in the same dll? Sounds like a dependency problem like it just can't find the dll on the hard drive that contains Foo.Bar.

Edit: Okay the above is obviously not the problem...

Probably a class you're using in the initializer requires a dependency that's not on the production machine... I don't see anything in your code but maybe it's in the part you left out. I would assume you have the full .net framework loaded on the production machine. Are you using any objects in the part of the code you left out that would directly or indirectly call code from any other in house or 3rd party dlls?

Another Edit: Actually I don't think code in the part you left out would be able to cause this error because it shouldn't run automatically when the class initializes. Are you sure there's not any other code you're leaving out? I don't see anything here that looks like it could cause that kind of exception.

It looks like "private static byte[] aes256Key = null;" is the only line even capable of causing this exception, but I think it's pretty clear that this line is not going to do that.

Upvotes: 0

Petar Ivanov
Petar Ivanov

Reputation: 93030

Foo.Aes256Key won't even compile, because Foo is your namespace...

Upvotes: 0

Related Questions