Как перезагрузить 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