Как перезагрузить RouteTable, когда коллекция веб-страниц изменилась?

В моем Global.asax подать на Application_Start Я создаю определенное количество маршрутов в RouteTable.Routes циклически просматривая список веб-страниц, собранных из базы данных. Это работает нормально, все маршруты созданы и функционируют как требуется. Но в моем веб-приложении пользователь может изменить базу данных и, следовательно, коллекцию веб-страниц. Это означает, что в течение жизненного цикла приложения некоторые маршруты становятся недействительными, и следует добавлять новые маршруты.

Я хочу сделать следующее: в тот момент, когда пользователь изменяет что-либо в коллекции веб-страниц, я хотел бы очистить таблицу RouteTable и перезагрузить ее, снова выполнив циклический просмотр (измененной) коллекции веб-страниц.

К сожалению Application_Start в Global.asax запускается только один раз, а именно в начале приложения. Я пытался переместить его в Session_Start что приводит к нежелательному поведению из-за RoutesTable быть статичным

Как я могу дать своему пользователю возможность изменять коллекцию веб-страниц на лету, сохраняя при этом статичность RouteTable оставаться в синхронизации?

редактировать

На данный момент я делаю что-то вроде этого (псевдокод):

public class WebPageInfo      // represents a record in the database
{
 public string Title;         //  My nice page
 public string Url;           //  NicePage 
 public string PhysicalFile;  //  ~/Page.aspx
}

В Global.asax:

protected virtual void Application_Start(object sender, EventArgs e)
{
 foreach (WebPageInfo webPageInfo in webPageInfos)
 {
  RouteTable.RegisterRoute(webPageInfo.Title, webPageInfo.Url, webPageInfo.PhysicalFile);
 }
}

Проблема заключается в том, что в течение жизненного цикла приложения пользователи могут добавлять / изменять / удалять записи в webPageInfosКак мне обновить RouteTable с этими изменениями?

2 ответа

Решение

Ответ от usbsnowcrash движется в правильном направлении. Вы уже знаете, как загрузить RouteTable информация, так что вместо того, чтобы запекать этот код непосредственно в Application_Start метод, поместите его в отдельный метод, который может быть вызван - возможно, что-то вроде RegisterRoutes, Application_Start метод будет вызывать RegisterRoutes выполнить начальную загрузку. В коде, который записывает изменения в коллекцию страниц, после того, как обновления были зафиксированы, вызовите RegisterRoutes перезагрузить RouteTable.

Вы захотите включить некоторые вызовы безопасности потока, такие как RouteTable.Routes.GetWriteLock() и вы также захотите очистить маршруты перед перезагрузкой всего из источника данных (как упомянуто в usbsnowcrash).

Я видел эту технику, используемую с классом "Bootstrapper", который обеспечивает static (Shared в VB) метод, который может быть вызван по мере необходимости. Хитрость заключается в том, чтобы сделать метод отдельным от Application_Start метод, чтобы вы могли выполнить код, не полагаясь исключительно на жизненный цикл приложения. Обязательно включайте "очищающие" вызовы, чтобы все начиналось с нуля при каждом вызове метода.

RouteTable можно заменить. Я хотел бы иметь какое-нибудь событие опроса, которое проверяет БД каждые 10 минут или около того, и если оно обнаружит изменение, замените таблицу маршрутизации (убедитесь, что этот код безопасен для потоков). Вот как может выглядеть код для обновления (при условии, что AddAllRuleSets - это функция, которую вы пишете для добавления всех наборов правил из БД).

        'somewhat threadsafe
        With System.Web.Routing.RouteTable.Routes
            Using .GetWriteLock()
                routes.Clear()
                'readd routes from your db
                AddAllRulesets()
            End Using
        End With
Другие вопросы по тегам