2010-03-23 3 views
6

Ich habe eine große Anwendung, die derzeit als eine Mischung aus WebForms und MVC 2.0 existiert. Start meiner Anwendung ist schrecklich, und der Schuldige ist in erster Linie wegen der AreaRegistration.RegisterAllAreas Aufruf. Genauer gesagt verwendet es die System.Web. Compilation.BuildManager.GetReferencedAssemblies, um alle Typen in Assemblys aufzuzählen, auf die die Anwendung direkt verweist, und sie zu testen, um zu sehen, ob sie von AreaRegistration stammen.Bereitstellen oder Filtern von Assemblys beim Registrieren von Bereichen für eine ASP.NET MVC 2.0-Anwendung

Leider habe ich eine Reihe von Drittanbieter-Assemblies, die sehr umfangreich sind, so dass diese Anfangslast ziemlich schlecht sein kann. Ich hätte viel bessere Ergebnisse, wenn ich ihm sagen könnte, welche Assemblies nach AreaRegistrations suchen, oder sogar Bereiche vorläufig manuell registrieren.

Ich kann alle Interna von AreaRegistration sammeln, um die Registrierung zu erstellen und aufzurufen, aber ich bin nur neugierig, ob andere hatten und um dieses Problem gearbeitet haben.

Antwort

12

Ich habe das folgende Dienstprogramm zusammengestellt, um Baugruppen für die Registrierung von Bereichen zu isolieren. Ich musste die Interna Bereich Registrierung Hack, aber sie scheinen nicht sehr kompliziert, und dies recht gut für mich gelaufen:

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)); 
     } 
    } 
} 

Der einfachste Weg, dies zu nutzen, für mich ist

AreaRegistrationUtil.RegisterAreasForAssemblyOf<SomeTypeInTargetAssembly>(); 

Dies hat zu einer spürbaren Verbesserung der Startzeit geführt, auf Kosten, dass es nicht möglich ist, einen Bereich zu verlassen und die Anwendung automatisch registrieren zu lassen. Das ist mir in diesem Fall jedoch nicht wichtig.

+0

Was ist die SomeTypeInTargetAssembly? Ich habe versucht, dies meinem Global.asax zu nennen, aber ich habe keine Ahnung, worum es geht. –

+0

Es ist ein Typ in der Baugruppe, der die Bereiche enthält. Ich denke, es ist ziemlich klar. –

+0

Liebe das. Habe meine 1104ms init in 14ms umgewandelt. –

2

Ich bin nicht 100% sicher, ob dies in diesem speziellen Fall hilft, aber könnten Sie alle Ihre 3rd-Party-DLLs in einer DLL kombinieren (wodurch die Verarbeitung aller einzelnen Dateien entfernt wird). Das haben wir mit ILMerge zur Build-Zeit gemacht. Klappt wunderbar. Es muss immer noch die Metadaten für die DLL (die jetzt ein bisschen größer sein), aber es muss nicht so viel IO zu tun.

+0

Ja, das ist ein interessanter Vorschlag für ein viel größeres Problem, aber es gibt Komplikationen bei der Umsetzung. Danke für den Vorschlag sowieso. – HackedByChinese

Verwandte Themen