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.
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;
}
To ensure the assembly is what we want, we have 3 conditions :
- the assembly is not in the GAC
- the assembly is no dynamic
- the assembly is not generated (to avoid temporary asp.net files
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.
What I am looking for now is :
1) Are my assembly validation conditions enough ? (I may have forgotten cases)
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...)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…