comment recharger RouteTable lorsque la collection de pages Web a changé?
-
29-10-2019 - |
Question
Dans mon fichier Global.asax
sur Application_Start
, je crée un certain nombre de routes dans RouteTable.Routes
en parcourant une liste de pages Web collectées à partir d'une base de données. Cela fonctionne bien, tous les itinéraires sont créés et fonctionnent selon les besoins. Mais dans mon application Web, l'utilisateur peut modifier la base de données et donc la collection de pages Web. Cela signifie que pendant le cycle de vie de l'application, certaines routes deviennent invalides et que de nouvelles routes doivent être ajoutées.
Ce que je souhaite faire, c'est: dès que l'utilisateur modifie quelque chose dans la collection de pages Web, je souhaite effacer la RouteTable et la recharger en parcourant à nouveau la collection de pages Web (modifiée).
Malheureusement, le Application_Start
dans Global.asax
n'est exécuté qu'une seule fois, à savoir au début de l'application. J'ai essayé de le déplacer vers Session_Start
, ce qui entraîne un comportement indésirable car le RoutesTable
est statique.
Comment donner à mon utilisateur la possibilité de modifier la collection de pages Web à la volée tout en gardant le code générique statique "synchronisé" avec lui?
Modifier
Pour le moment, je fais quelque chose comme ça (pseudo-code):
public class WebPageInfo // represents a record in the database
{
public string Title; // My nice page
public string Url; // NicePage
public string PhysicalFile; // ~/Page.aspx
}
Dans Global.asax:
protected virtual void Application_Start(object sender, EventArgs e)
{
foreach (WebPageInfo webPageInfo in webPageInfos)
{
RouteTable.RegisterRoute(webPageInfo.Title, webPageInfo.Url, webPageInfo.PhysicalFile);
}
}
Le problème est que pendant le cycle de vie de l'application, les utilisateurs peuvent ajouter / modifier / supprimer des enregistrements dans le RouteTable
, comment mettre à jour la RouteTable avec ces changements?
La solution
La réponse de usbsnowcrash va dans la bonne direction. Vous savez déjà comment charger les informations RouteTable
, donc plutôt que de cuire ce code directement dans la méthode Application_Start
, placez-le dans une méthode distincte qui peut être appelée - peut-être quelque chose comme RegisterRoutes
. La méthode Application_Start
appellerait RegisterRoutes
pour effectuer le chargement initial. Dans le code qui écrit les modifications apportées à la collection de pages, une fois les mises à jour validées, appelez RegisterRoutes
pour recharger la RouteTable.
Vous voudrez inclure des appels de sécurité des threads tels que RouteTable.Routes.GetWriteLock()
et vous voudrez également effacer les routes avant de tout recharger à partir de la source de données (comme mentionné par usbsnowcrash ).
J'ai vu cette technique utilisée avec une classe "Bootstrapper" qui fournit une méthode static
(Shared
dans VB) qui peut être appelée selon les besoins. L'astuce consiste à en faire une méthode distincte de la méthode Application_Start
afin que vous puissiez exécuter le code sans vous fier uniquement au cycle de vie de l'application. Assurez-vous d'inclure les appels "clearing" pour que les choses recommencent à zéro à chaque fois que la méthode est invoquée.
Autres conseils
RouteTable peut être remplacé.Ce que je ferais, c'est avoir un événement d'interrogation qui vérifie la base de données toutes les 10 minutes environ et s'il détecte un changement, remplacez la table de routage (assurez-vous de rendre ce code threadsafe).Voici à quoi pourrait ressembler le code pour effectuer la mise à jour (en supposant que AddAllRuleSets est une fonction que vous écrivez pour ajouter tous les ensembles de règles de la base de données).
'somewhat threadsafe
With System.Web.Routing.RouteTable.Routes
Using .GetWriteLock()
routes.Clear()
'readd routes from your db
AddAllRulesets()
End Using
End With