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

В моем 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 ]

6 голосов
/ 24 февраля 2011

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

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

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

2 голосов
/ 20 февраля 2011

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
...