C# 为ASP.NET MVC 2.0应用程序注册区域时提供或筛选程序集
我有一个大型应用程序,它目前是WebForms和MVC2.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 不幸的是,我有许多第三方程序集,这些程序集碰巧非常广泛,因此初始加载可能非常糟糕。如果我
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,但我不知道它是什么。程序集中的某个类型包含