Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetEntryAssembly for web applications

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...)

like image 672
Mose Avatar asked Nov 25 '10 13:11

Mose


People also ask

What is Assembly Getentryassembly ()?

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.

What is System reflection Assembly?

Namespace: System.Reflection. Summary. Defines an Assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.


1 Answers

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;     } 
like image 87
quentin-starin Avatar answered Sep 29 '22 11:09

quentin-starin