2010-03-23 8 views
6

Tôi có một ứng dụng lớn hiện đang tồn tại dưới dạng lai của WebForms và MVC 2.0. Khởi động ứng dụng của tôi là đáng sợ, và thủ phạm chủ yếu là do cuộc gọi AreaRegistration.RegisterAllAreas. Cụ thể hơn, rằng nó đang sử dụng System.Web. Compilation.BuildManager.GetReferencedAssemblies để liệt kê tất cả các loại trong các hội đồng được tham chiếu trực tiếp bởi ứng dụng và kiểm tra chúng để xem chúng có xuất phát từ AreaRegistration hay không.Cung cấp hoặc lọc các bộ phận khi đăng ký các khu vực cho ứng dụng ASP.NET MVC 2.0

Thật không may, tôi có một số hội đồng bên thứ ba xảy ra khá rộng rãi, vì vậy tải ban đầu này có thể khá tệ. Tôi sẽ có kết quả tốt hơn nhiều nếu tôi có thể nói với nó mà hội đồng để tìm kiếm AreaRegistrations, hoặc thậm chí đăng ký các khu vực bằng tay trong thời gian này.

Tôi có thể thu thập tất cả các nội bộ của AreaRegistration để tạo và gọi đăng ký, nhưng tôi chỉ tò mò nếu những người khác đã gặp phải và khắc phục sự cố này.

Trả lời

12

Tôi đã tập hợp các tiện ích sau đây để cô lập Hội đồng đăng ký Khu vực. Tôi đã phải hack ra internals đăng ký khu vực, nhưng họ dường như không terribly phức tạp và điều này đã được chạy khá tốt đối với tôi:

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

Cách dễ nhất để sử dụng này, đối với tôi, là

AreaRegistrationUtil.RegisterAreasForAssemblyOf<SomeTypeInTargetAssembly>(); 

Điều này đã có những cải tiến đáng chú ý trong thời gian khởi động, với chi phí không thể thả trong một khu vực và yêu cầu ứng dụng tự động đăng ký. Tuy nhiên, đó không phải là một mối quan tâm của tôi trong trường hợp này.

+0

SomeTypeInTargetAssembly là gì? Tôi đã thử gọi nó là Global.asax nhưng tôi không biết nó là gì. –

+0

Đó là một số loại trong hội đồng có chứa các khu vực. Tôi nghĩ nó khá rõ ràng. –

+0

Tình yêu này. Đã biến chiếc 1104ms của tôi thành 14ms. –

2

Tôi không chắc chắn 100% nếu điều này sẽ giúp ích trong trường hợp cụ thể này nhưng bạn có thể kết hợp tất cả các dll của bên thứ ba thành một dll (do đó loại bỏ việc xử lý tất cả các tệp riêng lẻ). Đây là những gì chúng tôi đã làm bằng cách sử dụng ILMerge tại thời gian xây dựng. Làm việc như một say mê. Nó vẫn sẽ cần phải nhìn vào siêu dữ liệu cho dll (mà bây giờ sẽ lớn hơn một chút) nhưng nó sẽ không phải làm nhiều IO.

+0

Vâng, đó là một gợi ý thú vị cho một vấn đề lớn hơn nhiều, nhưng có những biến chứng để thực hiện điều đó. Cảm ơn cho đề nghị anyways. – HackedByChinese