2010-04-02 4 views
1

Мы пытаемся удалить global.asax из наших многочисленных веб-приложений в пользу HttpModules, которые находятся в общей базе кода. Это работает очень хорошо для многих приложений, таких как BeginRequest и PostAuthentication, но в HttpModule нет события запуска приложения.Как я могу использовать или имитировать приложение OnStart в HttpModule?

Я могу придумать пару вонючих способов преодолеть этот дефицит. Например, я могу, вероятно, сделать это:

protected virtual void BeginRequest(object sender, EventArgs e) 
{ 
    Log.Debug("Entered BeginRequest..."); 
    var app = HttpContext.Current.Application; 
    var hasBeenSet app["HasBeenExecuted"] == null ? false : true; 

    if(!hasBeenSet) 
    { 
     app.Lock(); 
     // ... do app level code 

     app.Add("HasBeenExecuted", true); 
     app.Unlock(); 
    } 

    // do regular begin request stuff ... 
} 

Но это просто не так хорошо пахнет.

Каков наилучший способ вызвать какую-либо логику запуска приложения без наличия global.asax?

ответ

1

Просто держать статический BOOL в HttpModule:

private static bool _hasApplicationStarted = false; 
private static object _locker = new object(); 

private void EnsureStarted() 
{ 
    if (_hasApplicationStarted) return; 

    lock (_locker) 
    { 
     if (_hasApplicationStarted) return; 

     // perform application startup here 

     _hasApplicationStarted = true; 
    } 
} 

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

+0

@John: Это выглядит как одноэлементный узор. Я бы немного беспокоился об использовании статичности из-за проблем с потоками, когда, скажем, одновременно поступают несколько запросов. Объект приложения, по крайней мере, имеет некоторые простые блокировки/разблокировки, чтобы помочь в этом. –

+0

@John: Я вижу, вы добавили, что сейчас ... :) –

+0

@ Парусное судно: замок всегда был там. Ответ не редактировался. –

0

HttpModules и HttpHandlers будут выполняться при каждом отдельном запросе, а событие запуска приложения Global.asax - это когда приложение запускается, и только один раз.

Вы можете создать общий файл global.asax, который будет загружать все сборки с помощью определенного интерфейса, а затем забросить DLL, которую вы хотите выполнить для этого конкретного приложения. Или даже зарегистрируйте их в своем web.config и попросите свой общий файл global.asax прочитать ключи, а затем загрузите и выполните код, который вы хотите.

Я думаю, что это лучше, чем добавлять код приложения в модуль и проверять переменную состояния.

+0

Одна из целей - удалить global.asax. Если мы не сможем сделать это, мы можем принять другие подходы, которые будут более простыми, чем то, что вы описываете (например, мы можем сделать вызов Application_Start() статическим методом в классе HttpModule). –

+1

Угадайте, я просто задавался вопросом, почему проще избавиться от global.asax, чем включить HttpModule? –

+0

Ну, я уже использую HttpModule, который уже зарегистрирован в файле web.config. Я бы сказал, добавив некоторое отражение и файл ввода-вывода в событие запуска приложения, чтобы «загрузить все assmeblies с определенным интерфейсом», не так просто, как вызвать статический метод в другом классе. –