C# 为ASP.NET MVC 2.0应用程序注册区域时提供或筛选程序集

C# 为ASP.NET MVC 2.0应用程序注册区域时提供或筛选程序集,c#,asp.net-mvc-2,registration,asp.net-mvc-areas,C#,Asp.net Mvc 2,Registration,Asp.net Mvc Areas,我有一个大型应用程序,它目前是WebForms和MVC2.0的混合体。我的应用程序启动很糟糕,罪魁祸首主要是因为AreaRegistration.RegisteralAreas调用。更具体地说,它正在使用System.Web。Compilation.BuildManager.getReferenceAssembly枚举应用程序直接引用的程序集中的所有类型,并测试它们是否派生自AreaRegistration 不幸的是,我有许多第三方程序集,这些程序集碰巧非常广泛,因此初始加载可能非常糟糕。如果我

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

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


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

我不能100%确定这在这种特定情况下是否会有所帮助,但您能将所有第三方DLL合并到一个DLL中吗(因此删除了对所有单个文件的处理)。这就是我们在构建时使用ILMerge所做的。工作起来很有魅力。它仍然需要查看dll的元数据(现在会大一点)但是它不需要做那么多IO。

我将以下实用程序组合在一起,以隔离用于注册区域的程序集。我必须破解区域注册的内部结构,但它们似乎并不十分复杂,这对我来说运行得相当好:

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));
        }
    }
}
使用系统;
使用System.Linq;
运用系统反思;
使用System.Web.Mvc;
使用System.Web.Routing;
命名空间MyCompany.Web.Mvc
{
/// 
///提供有用的实用程序,用于执行区域注册(可能还不够)。
/// 
公共静态类AreaRegistrationUtil
{
/// 
///注册程序集中包含给定类型的所有区域。
/// 
///派生自并具有默认构造函数的类型。
公共静态无效注册表AreasForassemblyof()
其中T:AreaRegistration,new()
{
RegisterAreasForAssemblyOf(空);
}
/// 
///注册程序集中包含给定类型的所有区域。
/// 
///派生自并具有默认构造函数的类型。
///包含将传递给区域注册的状态的对象。
公共静态无效注册表AreasForassemblyof(对象状态)
其中T:AreaRegistration,new()
{
寄存器区域组合(状态,类型(T).Assembly);
}
/// 
///注册在给定程序集中找到的所有区域。
/// 
///包含预期区域注册的对象。
公共静态无效注册表区域组合(参数程序集[]程序集)
{
RegisterAreasForAssemblies(null,程序集);
}
/// 
///注册在给定程序集中找到的所有区域。
/// 
///包含将传递给区域注册的状态的对象。
///包含预期区域注册的对象。
公共静态无效注册表区域组合(对象状态,参数程序集[]程序集)
{
foreach(输入
从程序集中的程序集
来自程序集中的类型。GetTypes()
其中IsAreaRegistrationType(类型)
选择类型)
{
RegisterArea((AreaRegistration)Activator.CreateInstance(类型),状态);
}
}
/// 
///使用指定的类型执行区域注册。
/// 
///派生自并具有默认构造函数的类型。
公共静态无效注册表区域()
其中T:AreaRegistration,new()
{
注册区域(空);
}
/// 
///使用指定的类型执行区域注册。
/// 
///派生自并具有默认构造函数的类型。
///包含将传递给区域注册的状态的对象。
公共静态无效注册表区域(对象状态)
其中T:AreaRegistration,new()
{
var registration=Activator.CreateInstance();
注册区域(注册,州);
}
专用静态无效注册表区域(区域注册、对象状态)
{
var context=新的AreaRegistrationContext(registration.AreaName,RouteTable.Routes,state);
字符串ns=registration.GetType().Namespace;
if(ns!=null)context.Namespaces.Add(string.Format(“{0}.*”,ns));
注册。注册区域(上下文);
}
/// 
///返回指定的类型是否可分配给。
/// 
///A。
///如果指定的类型可分配给,则为True;否则为false。
私有静态布尔IsAreaRegistrationType(类型)
{
return(typeof(AreaRegistration).IsAssignableFrom(type)&(type.GetConstructor(type.EmptyTypes)!=null);
}
}
}
对我来说,最简单的方法就是

AreaRegistrationUtil.RegisterAreasForAssemblyOf<SomeTypeInTargetAssembly>();
AreaRegistrationUtil.RegisterAreasForAssemblyOf();

这在启动时间上有了显著的改进,但代价是无法进入某个区域并让应用程序自动注册。然而,在这种情况下,这不是我关心的问题。

是的,这是一个关于更大问题的有趣建议,但实现这一点有很多复杂之处。感谢suggestion。什么是SomeTypeInTargetAssembly?我尝试将其调用到我的Global.asax,但我不知道它是什么。程序集中的某个类型包含