2010-03-23 3 views
6

J'ai une grande application qui existe actuellement en tant qu'hybride de WebForms et de MVC 2.0. Le démarrage de mon application est horrible, et le coupable est principalement à cause de l'appel AreaRegistration.RegisterAllAreas. Plus précisément, il utilise le System.Web. Compilation.BuildManager.GetReferencedAssemblies pour énumérer tous les types d'assemblages directement référencés par l'application et les tester pour voir s'ils dérivent de AreaRegistration.Fournir ou filtrer des assemblages lors de l'enregistrement de zones pour une application ASP.NET MVC 2.0

Malheureusement, j'ai un certain nombre d'assemblages tiers qui sont assez étendus, donc cette charge initiale peut être assez mauvaise. J'aurais de meilleurs résultats si je pouvais dire quels sont les assemblages à rechercher AreaRegistrations, ou même enregistrer des zones manuellement pour le moment.

Je peux rassembler tous les internes de AreaRegistration pour créer et invoquer l'enregistrement, mais je suis juste curieux de savoir si d'autres ont eu et ont travaillé autour de ce problème.

Répondre

12

J'ai assemblé l'utilitaire suivant pour isoler les assemblages pour l'enregistrement de zones. Je devais pirater les entrailles de l'enregistrement de la zone, mais ils ne semblent pas très compliqué et cela a fonctionné assez bien pour moi:

using System; 
using System.Linq; 
using System.Reflection; 
using System.Web.Mvc; 
using System.Web.Routing; 

namespace MyCompany.Web.Mvc 
{ 
    /// <summary> 
    /// Provides helpful utilities for performing area registration, where <see cref="AreaRegistration.RegisterAllAreas()"/> may not suffice. 
    /// </summary> 
    public static class AreaRegistrationUtil 
    { 
     /// <summary> 
     /// Registers all areas found in the assembly containing the given type. 
     /// </summary> 
     /// <typeparam name="T">A type that derives from <see cref="AreaRegistration"/> and has a default constructor.</typeparam> 
     public static void RegisterAreasForAssemblyOf<T>() 
      where T : AreaRegistration, new() 
     { 
      RegisterAreasForAssemblyOf<T>(null); 
     } 

     /// <summary> 
     /// Registers all areas found in the assembly containing the given type. 
     /// </summary> 
     /// <typeparam name="T">A type that derives from <see cref="AreaRegistration"/> and has a default constructor.</typeparam> 
     /// <param name="state">An object containing state that will be passed to the area registration.</param> 
     public static void RegisterAreasForAssemblyOf<T>(object state) 
      where T : AreaRegistration, new() 
     { 
      RegisterAreasForAssemblies(state, typeof (T).Assembly); 
     } 

     /// <summary> 
     /// Registers all areas found in the given assemblies. 
     /// </summary> 
     /// <param name="assemblies"><see cref="Assembly"/> objects containing the prospective area registrations.</param> 
     public static void RegisterAreasForAssemblies(params Assembly[] assemblies) 
     { 
      RegisterAreasForAssemblies(null, assemblies); 
     } 

     /// <summary> 
     /// Registers all areas found in the given assemblies. 
     /// </summary> 
     /// <param name="state">An object containing state that will be passed to the area registration.</param> 
     /// <param name="assemblies"><see cref="Assembly"/> objects containing the prospective area registrations.</param> 
     public static void RegisterAreasForAssemblies(object state, params Assembly[] assemblies) 
     { 
      foreach (Type type in 
       from assembly in assemblies 
       from type in assembly.GetTypes() 
       where IsAreaRegistrationType(type) 
       select type) 
      { 
       RegisterArea((AreaRegistration) Activator.CreateInstance(type), state); 
      } 
     } 

     /// <summary> 
     /// Performs area registration using the specified type. 
     /// </summary> 
     /// <typeparam name="T">A type that derives from <see cref="AreaRegistration"/> and has a default constructor.</typeparam> 
     public static void RegisterArea<T>() 
      where T : AreaRegistration, new() 
     { 
      RegisterArea<T>(null); 
     } 

     /// <summary> 
     /// Performs area registration using the specified type. 
     /// </summary> 
     /// <typeparam name="T">A type that derives from <see cref="AreaRegistration"/> and has a default constructor.</typeparam> 
     /// <param name="state">An object containing state that will be passed to the area registration.</param> 
     public static void RegisterArea<T>(object state) 
      where T : AreaRegistration, new() 
     { 
      var registration = Activator.CreateInstance<T>(); 
      RegisterArea(registration, state); 
     } 

     private static void RegisterArea(AreaRegistration registration, object state) 
     { 
      var context = new AreaRegistrationContext(registration.AreaName, RouteTable.Routes, state); 
      string ns = registration.GetType().Namespace; 

      if (ns != null) context.Namespaces.Add(string.Format("{0}.*", ns)); 

      registration.RegisterArea(context); 
     } 

     /// <summary> 
     /// Returns whether or not the specified type is assignable to <see cref="AreaRegistration"/>. 
     /// </summary> 
     /// <param name="type">A <see cref="Type"/>.</param> 
     /// <returns>True if the specified type is assignable to <see cref="AreaRegistration"/>; otherwise, false.</returns> 
     private static bool IsAreaRegistrationType(Type type) 
     { 
      return (typeof (AreaRegistration).IsAssignableFrom(type) && (type.GetConstructor(Type.EmptyTypes) != null)); 
     } 
    } 
} 

manière la plus simple à utiliser, pour moi, est

AreaRegistrationUtil.RegisterAreasForAssemblyOf<SomeTypeInTargetAssembly>(); 

Cela a permis d'améliorer sensiblement le temps de démarrage, au prix de ne pas pouvoir tomber dans une zone et de demander à l'application de l'enregistrer automatiquement. Cependant, ce n'est pas une de mes préoccupations dans ce cas.

+0

qu'est ce que SomeTypeInTargetAssembly? J'ai essayé d'appeler ceci à mon Global.asax mais je n'ai aucune idée de quoi il s'agit. –

+0

C'est un type dans l'assemblage qui contient les zones. Je pense que c'est assez clair. –

+0

Aime ça. Transformé mon init 1104ms en 14ms. –

2

Je ne suis pas sûr à 100% si cela aidera dans ce cas précis, mais pourriez-vous combiner toutes vos DLLs tiers en une seule DLL (d'où le retrait de tous les fichiers individuels). C'est ce que nous avons fait en utilisant ILMerge au moment de la construction. Fonctionne comme un charme. Il faudra encore regarder les métadonnées pour la DLL (qui sera maintenant un peu plus grande) mais il n'aura pas à faire autant d'E/S.

+0

Oui, c'est une suggestion intéressante pour un problème beaucoup plus important, mais il y a des complications à mettre en place. Merci pour la suggestion de toute façon. – HackedByChinese

Questions connexes