Тип инициализатора выдал исключение при доступе к статическому свойству - PullRequest
1 голос
/ 16 ноября 2011

У меня определено следующее статическое свойство:

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

В другом классе во внутреннем пространстве имен я получаю доступ к этому свойству:

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 используетсяисполняемое консольное приложение.Когда я запускаю это консольное приложение вручную из среды сборки, я не вижу никаких проблем.Однако, когда исполняемый файл запускается в контексте процесса сборки (на сервере с потенциально другой средой), я вижу следующее исключение времени выполнения:

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

Исполняемый проект в VS2008 имеет ссылку наFoo проект, который определяет пространство имен Foo.

Я делаю здесь что-то принципиально неправильное?Что может быть причиной этого?

Ответы [ 3 ]

1 голос
/ 16 ноября 2011

Трудно работать в «статическом мире», не видя полного кода. Тем не менее, есть несколько областей, над которыми вы можете работать (лично), чтобы найти причину.

aes256Key = new byte[32];
// Fill in key...
return aes256Key;
  1. Целесообразно проверить возможное исключение в логике "Введите ключ"

  2. Определите статический конструктор для этого бара и инициализируйте все ваши статические поля.

  3. Убедитесь, что вы звоните по следующему номеру RuntimeHelpers.RunClassConstructor(typeof(Bar).TypeHandle) прежде чем даже получить доступ к любому static/instance field/member/method.

    static void Main(string[] args)

    {* * тысяча двадцать-один

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

    }

RuntimeHelpers.RunClassConstructor действительно запрашивает у среды выполнения вызов статического конструктора независимо от причин, указанных в CLI. Это обеспечивает детерминированный порядок инициализации блока. Это необходимо, потому что инициализатор типа верит в Ленивую инициализацию.

0 голосов
/ 16 ноября 2011

Foo.Cryptography и Foo.Bar находятся в одной и той же dll? Похоже, проблема зависимости, как будто он просто не может найти DLL на жестком диске, который содержит Foo.Bar.

Редактировать: Хорошо, вышеизложенное, очевидно, не проблема ...

Вероятно, класс, который вы используете в инициализаторе, требует зависимости, которой нет на рабочей машине ... Я ничего не вижу в вашем коде, но, возможно, это та часть, которую вы пропустили. Я бы предположил, что у вас есть полный .net Framework, загруженный на производственную машину. Используете ли вы какие-либо объекты в той части кода, которую вы пропустили, которая будет прямо или косвенно вызывать код из любых других внутренних или сторонних библиотек?

Другое редактирование: На самом деле я не думаю, что код в той части, которую вы пропустили, мог вызвать эту ошибку, потому что он не должен запускаться автоматически при инициализации класса. Вы уверены, что нет никакого другого кода, который вы пропускаете? Я не вижу здесь ничего, что могло бы стать причиной такого исключения.

Это выглядит как "приватный статический байт [] aes256Key = null;" является единственной линией, способной вызвать это исключение, но я думаю, что совершенно ясно, что эта строка не собирается этого делать.

0 голосов
/ 16 ноября 2011

Foo.Aes256Key даже не скомпилируется, потому что Foo это ваше пространство имен ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...