用于 Web 应用程序的 GetEntryAssembly [英] GetEntryAssembly for web applications
问题描述
Assembly.GetEntryAssembly() 不适用于网络应用程序.
Assembly.GetEntryAssembly() does not work for web applications.
但是...我真的需要这样的东西.我使用一些在网络和非网络应用程序中使用的深层嵌套代码.
But... I really need something like that. I work with some deeply-nested code that is used in both web and non-web applications.
我目前的解决方案是浏览 StackTrace 以找到第一个被调用的程序集.
My current solution is to browse the StackTrace to find the first called assembly.
/// <summary>
/// Version of 'GetEntryAssembly' that works with web applications
/// </summary>
/// <returns>The entry assembly, or the first called assembly in a web application</returns>
public static Assembly GetEntyAssembly()
{
// get the entry assembly
var result = Assembly.GetEntryAssembly();
// if none (ex: web application)
if (result == null)
{
// current method
MethodBase methodCurrent = null;
// number of frames to skip
int framestoSkip = 1;
// loop until we cannot got further in the stacktrace
do
{
// get the stack frame, skipping the given number of frames
StackFrame stackFrame = new StackFrame(framestoSkip);
// get the method
methodCurrent = stackFrame.GetMethod();
// if found
if ((methodCurrent != null)
// and if that method is not excluded from the stack trace
&& (methodCurrent.GetAttribute<ExcludeFromStackTraceAttribute>(false) == null))
{
// get its type
var typeCurrent = methodCurrent.DeclaringType;
// if valid
if (typeCurrent != typeof (RuntimeMethodHandle))
{
// get its assembly
var assembly = typeCurrent.Assembly;
// if valid
if (!assembly.GlobalAssemblyCache
&& !assembly.IsDynamic
&& (assembly.GetAttribute<System.CodeDom.Compiler.GeneratedCodeAttribute>() == null))
{
// then we found a valid assembly, get it as a candidate
result = assembly;
}
}
}
// increase number of frames to skip
framestoSkip++;
} // while we have a working method
while (methodCurrent != null);
}
return result;
}
为了确保程序集是我们想要的,我们有 3 个条件:
To ensure the assembly is what we want, we have 3 conditions :
- 程序集不在 GAC 中
- 程序集不是动态的
- 未生成程序集(以避免临时的 asp.net 文件
我遇到的最后一个问题是在单独的程序集中定义基页时.(我使用 ASP.Net MVC,但它与 ASP.Net 相同).在这种特殊情况下,返回的是单独的程序集,而不是包含页面的程序集.
The last problem I meet is when the base page is defined in a separate assembly. (I use ASP.Net MVC, but it'll be the same with ASP.Net). In that particular case, it's that separate assembly that is returned, not the one containing the page.
我现在正在寻找的是:
1) 我的程序集验证条件是否足够?(我可能忘记case了)
1) Are my assembly validation conditions enough ? (I may have forgotten cases)
2) 有没有办法从 ASP.Net 临时文件夹中的给定代码生成程序集获取有关包含该页面/视图的项目的信息?(我想不是,但谁知道呢...)
2) Is there a way, from a given code-generated assembly in the ASP.Net temporary folder, to get information about the project that contains that Page / View ? (I think not, but who knows...)
推荐答案
这似乎是获取 Web 应用程序的入口"或主程序集的可靠、简单的方法.
This seems to be a reliable, simple way to get the "entry" or main assembly for a web app.
如果您将控制器放在一个单独的项目中,您可能会发现 ApplicationInstance 的基类与包含视图的 MVC 项目不在同一个程序集中 - 但是,这种设置似乎很少见(我提到它是因为我我曾经尝试过这种设置,不久前有一些博客支持这个想法).
If you put controllers in a separate project, you may find that the base class of ApplicationInstance is not in the same assembly as your MVC project that contains the Views - but, this setup seems pretty rare (I mention it because I've tried this setup at one point, and a while back a few blogs supported the idea).
static private Assembly GetWebEntryAssembly()
{
if (System.Web.HttpContext.Current == null ||
System.Web.HttpContext.Current.ApplicationInstance == null)
{
return null;
}
var type = System.Web.HttpContext.Current.ApplicationInstance.GetType();
while (type != null && type.Namespace == "ASP") {
type = type.BaseType;
}
return type == null ? null : type.Assembly;
}
这篇关于用于 Web 应用程序的 GetEntryAssembly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!