This was such an interesting question. It took me a while to understand the Asp.Net bootstrapping pipeline. I will not go into detail so much because it would take a lot so I will leave the details to OP.
Basically, Asp.Net framework dynamically creates an assembly and creates a dynamically created type which inherits your MvcApplication
.
So here is the default MvcApplication
public class MvcApplication : HttpApplication {
public static void Application_Start() {
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
So what do I mean by Asp.Net framework dynamically creating another assembly and a type? You will notice that by checking the following code→
Let us modify Application_Start
method:
public static void Application_Start() {
var whatIsMyType = GetType();
//You will see that our actual type is of ASP.global_asax,
//which inherits MvcApplication, which inherits HttpApplication
//Other Stuff...
}
Where does ASP.global_asax
type is created? You will need to dig deep into source code but let me give you a hint
So how does the actual ASP.global_asax looks like?
[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
public class global_asax : global::<YourNameSpace>.MvcApplication {
private static bool @__initialized;
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global_asax() {
if ((global::ASP.global_asax.@__initialized == false)) {
global::ASP.global_asax.@__initialized = true;
}
}
protected System.Web.Profile.DefaultProfile Profile {
get {
return ((System.Web.Profile.DefaultProfile)(this.Context.Profile));
}
}
}
Finally, we can move onto the actual answer: Why does making Application_Start
static make the application behave in an unexpected way?
In HttpApplicationFactory
class, which is used in the bootstrapping your application, there is the following line of code
methods = _theApplicationType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
foreach (MethodInfo m in methods) {
if (ReflectOnMethodInfoIfItLooksLikeEventHandler(m))
handlers.Add(m);
}
The puzzle is solved at _theApplicationType
. Please remember that this is of ASP.global_asax type
. Your static method Application_Start
is defined in MvcApplication
type so reflection will not find it through _theApplicationType
and as a result it will not be assigned to be called when application starts.
Here is a simple code to check this.
public class BaseClass {
public static void StaticMethodInBaseClass() {
}
}
public class DerivedClass {
public void DerivedClassMethod() {
}
}
//You will not get `StaticMethodInBaseClass` here
var methods = typeof(DerivedClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);