2010-12-14 3 views
0

Этот вопрос больше подходит для подтверждения моего диагноза проблемы, с которой мы столкнулись, или найти альтернативные объяснения.StructureMap не кажется готовым во время конструктора HttpModule - это правильно?

У нас есть HTTPModule, который перехватывает каждый запрос, сделанный в нашем приложении webforms. Задача состоит в том, чтобы перевести конкретные параметры запроса, которые посылают наши партнеры по интеграции.

Что еще более важно, он был подключен к StructureMap так:

public class SomeModule : IHttpModule 
{ 
    public SomeModule() 
    { 
     ObjectFactory.BuildUp(this); 
    } 

    public IDependency Dependency { get; set; } 
} 

В течение предыдущей версии, оказался, что модуль не впрыскивается к тому времени он выполнил его по обработке запросов. Это привело к некоторым (уродливым) оборонительным проверкам добавляется как:

public class SomeModule : IHttpModule 
{ 
    public SomeModule() 
    { 
     ObjectFactory.BuildUp(this); 
     if (SomeDependency == null) 
     { 
      // HACK: Not sure why this corrects the issue! 
      Dependency = ObjectFactory.GetInstance<ISomeDependency>(); 
     } 
    } 

    public IDependency Dependency { get; set; } 
} 

Вы заметите HACK комментарий - это решило проблему, но без уважительных причин.

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

public class SomeModule : IHttpModule 
{ 
    public IDependency Dependency { get; set; } 

    public void IHttpModule.Init(HttpApplication context) 
    { 
     Initialize(); 
     // the rest of the code 
    } 

    private bool _initialized; 
    private void Initialize() 
    { 
     if (_initialized) 
     { 
      return; 
     } 

     ObjectFactory.BuildUp(this); 
     _initialized = true; 
    } 
} 

Итак, мой у меня есть несколько вопросов вокруг этого поведения:

  • Мое подозрение, что StructureMap не полностью инициализирован/настроен, когда конструктор HttpModule был называться - согласен/не согласен, любой в поле зрения?
  • Я не нашел никаких справочных материалов, в которых указано, когда ожидать, что StructureMap будет инициализирован и готов к обслуживанию запросов. Есть ли такая документация?

ответ

0

Я бы не ожидал, что поведение будет очень предсказуемым, когда вы пытаетесь создать тип в его конструкторе. Многие действия, которые обычно считаются безопасными, не считаются безопасными в конструкторе (например, использование виртуального свойства в классе).

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

Чтобы ответить на вопрос, который у вас есть в конце вашего сообщения: Определить, когда StructureMap инициализируется разработчиком. В веб-приложении это почти всегда выполняется в Global.asax в Application_Start(). В этом случае я ожидаю, что контейнер будет готов, когда ваш модуль будет вызван.

+0

Вы можете ссылаться на любые ссылки на опасения относительно предсказуемости вызовов StructureMap внутри конструкторов? При поиске конкретных ответов я столкнулся с ссылками, где Палермо (один из авторов SM) использует 'BuildUp (this);' внутри конструкторов – STW

+0

http://codebetter.com/jeremymiller/2009/01/16/quot-buildup-quot -existing-objects-with-structuremap/ – STW

+0

Я не могу найти место, где они говорят, что это плохая идея. Но примером, который я бы дал, является наследование. Если вы вызываете BuildUp() в конструкторе, и он правильно заполняет зависимости, тогда это кажется прекрасным, но если в дереве наследования есть еще больше конструкторов, то это значение может быть перезаписано. –