NullReferenceException в конструкторе при разрешении зависимости с помощью Unity IOC для облачной службы Windows Azure

У меня есть облачная служба Windows Azure с веб-ролью и рабочей ролью. Обе роли используют контейнер Unity в корне композиции для регистрации типов (последние пакеты nuget на момент публикации).

Весь этот код отлично работает при запуске в эмуляторе Azure при отладке, однако, когда я создаю пакет и развертываю облачную службу, я сразу же сталкиваюсь с этой ошибкой при запуске ролей (веб-роль столкнется с этим, когда я нажму страница, которая зависит от рассматриваемого типа, в то время как рабочая роль сразу же попадет на нее при запуске).

Я получаю NullReferenceException следующим образом:

[ResolutionFailedException: Resolution of the dependency failed, type = "MyApp.Mvc.Controllers.HomeController", name = "(none)".
Exception occurred while: Calling constructor MyApp.Azure.Messaging.ServiceBusMessagingClient(System.String serviceBusConnectionString).
Exception is: NullReferenceException - Object reference not set to an instance of an object.

Вот код в ctor моего типа, который является клиентом-оболочкой для служебной шины Azure:

public ServiceBusMessagingClient(string serviceBusConnectionString)
    {
        Guard.NotNullOrEmpty(() => serviceBusConnectionString, serviceBusConnectionString);

        _log = LogFactory.GetCurrentClassLogger();

        ConnectionString = serviceBusConnectionString;

        _msgFactory = MessagingFactory.CreateFromConnectionString(ConnectionString);
        _retryPolicy = new RetryPolicy<ServiceBusTransientErrorDetectionStrategy>(RetryStrategy.DefaultClientRetryCount);
        _clients = new Dictionary<string, QueueClient>();
    }

А вот код моего загрузчика, который вызывается либо в веб-приложении app_start, либо в рабочей роли OnStart:

var sbConn = CloudConfigurationManager.GetSetting(Constants.KeyServiceBusConnectionString);
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>(new InjectionConstructor(sbConn));

Может ли кто-нибудь сказать мне, почему я получаю такое исключение? Я не вижу в коде ctor ничего, что могло бы привести к нулевой ссылке. И я не понимаю, почему это работает в эмуляторе, но не в облачном развертывании. Я уже проверил настройки облака, чтобы убедиться, что моя строка подключения присутствует. Спасибо!


person Thiago Silva    schedule 19.03.2013    source источник


Ответы (1)


Хорошо... Я обнаружил неясное изменение поведения с DEBUB на RELEASE при создании System.Reflection.StackFrame.

Мой метод LogFactory.GetCurrentClassLogger() выполняет следующий код:

StackFrame frame = new StackFrame(1, false);

По-видимому, в сборке RELEASE этот проход вверх по стеку даст нуль для frame.GetMethod().DeclaringType.

Таким образом, решение состояло в том, чтобы проверить значение null и использовать статическую строку для имени регистратора, если оно равно нулю. Узнавайте что-нибудь каждый день. Надеюсь, это поможет кому-то.

person Thiago Silva    schedule 20.03.2013