在为ASP.NET MVC 2.0应用程序注册区域时提供或过滤程序集

我有一个大型应用程序,目前作为WebForms和MVC 2.0的混合体存在。 启动我的应用程序是可怕的,罪魁祸首主要是因为AreaRegistration.RegisterAllAreas调用。 更具体地说,它正在使用System.Web. Compilation.BuildManager.GetReferencedAssemblies System.Web. Compilation.BuildManager.GetReferencedAssemblies枚举应用程序直接引用的程序集中的所有类型,并测试它们是否派生自AreaRegistration

不幸的是,我有许多第三方程序集恰好相当广泛,所以这个初始加载可能非常糟糕。 如果我可以告诉它哪些程序集要查找AreaRegistrations ,或者甚至手动注册区域,我会有更好的结果。

我可以收集AreaRegistration所有内部来创建和调用注册,但我只是好奇其他人是否已经解决了这个问题。

我将以下实用程序放在一起以隔离Assemblies以注册区域。 我不得不破解区域注册的内部,但它们看起来并不复杂,而且对我来说运行起来相当不错:

 using System; using System.Linq; using System.Reflection; using System.Web.Mvc; using System.Web.Routing; namespace MyCompany.Web.Mvc { ///  /// Provides helpful utilities for performing area registration, where  may not suffice. ///  public static class AreaRegistrationUtil { ///  /// Registers all areas found in the assembly containing the given type. ///  /// A type that derives from  and has a default constructor. public static void RegisterAreasForAssemblyOf() where T : AreaRegistration, new() { RegisterAreasForAssemblyOf(null); } ///  /// Registers all areas found in the assembly containing the given type. ///  /// A type that derives from  and has a default constructor. /// An object containing state that will be passed to the area registration. public static void RegisterAreasForAssemblyOf(object state) where T : AreaRegistration, new() { RegisterAreasForAssemblies(state, typeof (T).Assembly); } ///  /// Registers all areas found in the given assemblies. ///  ///  objects containing the prospective area registrations. public static void RegisterAreasForAssemblies(params Assembly[] assemblies) { RegisterAreasForAssemblies(null, assemblies); } ///  /// Registers all areas found in the given assemblies. ///  /// An object containing state that will be passed to the area registration. ///  objects containing the prospective area registrations. 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); } } ///  /// Performs area registration using the specified type. ///  /// A type that derives from  and has a default constructor. public static void RegisterArea() where T : AreaRegistration, new() { RegisterArea(null); } ///  /// Performs area registration using the specified type. ///  /// A type that derives from  and has a default constructor. /// An object containing state that will be passed to the area registration. public static void RegisterArea(object state) where T : AreaRegistration, new() { var registration = Activator.CreateInstance(); 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); } ///  /// Returns whether or not the specified type is assignable to . ///  /// A . /// True if the specified type is assignable to ; otherwise, false. private static bool IsAreaRegistrationType(Type type) { return (typeof (AreaRegistration).IsAssignableFrom(type) && (type.GetConstructor(Type.EmptyTypes) != null)); } } } 

对我来说,最简单的方法就是使用它

 AreaRegistrationUtil.RegisterAreasForAssemblyOf(); 

这在启动时间方面取得了明显的改进,代价是无法放入某个区域并让应用程序自动注册它。 但是,在这种情况下,这不是我的担忧。

我不是100%确定这是否有助于这个特定情况,但你可以将所有第三方dll组合成一个dll(因此删除所有单个文件的处理)。 这是我们在构建时使用ILMerge所做的。 奇迹般有效。 它仍然需要查看dll的元数据(现在会有点大),但它不需要做多少IO。