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 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...)
Assembly. The assembly that is the process executable in the default application domain, or the first executable that was executed by ExecuteAssembly(String). Can return null when called from unmanaged code.
Namespace: System.Reflection. Summary. Defines an Assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.
This seems to be a reliable, simple way to get the "entry" or main assembly for a web app.
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With