It doesn't load any DLLs automatically.
Every DLL it loads is directly related to a request. First, Global.asax is compiled (which may load some DLLs from bin
). Then, whatever HTTP modules and HTTP handlers are defined in web.config (there's some overlap with the previous step). Then the final aspx/asmx/... Some others might go for the ride as part of the configuration or something like that, but all the DLLs that are loaded are always loaded explicitly.
Thus, there is no "master" DLL. web.config, Global.asax and the actual requested file are the ones to decide what's actually going to happen. If you need to have a particular DLL loaded (and you don't simply have it referenced), you need to do it yourself.
EDIT:
Since this is a bit complicated, let me expand a bit.
The main thing to keep in mind here is that ASP.NET is always dynamically compiled - at least to an extent. At the very least, you always have to compile Global.asax
- no way around it. Now, dynamic compilation in ASP.NET has an important feature - it's out-of-process (at least for the legacy compiler - I'm not sure about Roslyn+). So whatever the compiler does to find references etc., doesn't actually reflect what's loaded to the worker process itself - and to your application domain in particular.
The dynamic compilation is handled by the BuildManager
class on the .NET side - http://referencesource.microsoft.com/#System.Web/Compilation/BuildManager.cs,fb803c621f3806a8. Since you asked about a "master DLL", the most relevant bit would be the code that handles Global.asax
compilation, which is one of the starting points of any ASP.NET application. The very initial compilation is handled by the EnsureTopLevelFilesCompiled
method. Looking through the code, you can easily see the first steps:
CompileResourcesDirectory();
CompileWebRefDirectory();
CompileCodeDirectories();
...
CompileGlobalAsax();
Most of this is slightly different for web sites vs web projects, as well as for pre-compiled sites, but we can pretty much ignore that. Now, the code isn't the simplest code in the world, but basically, it boils down to producing a bunch of assemblies - about one assembly per code directory. Again, this is done out of process - while the compiler has to load the binaries in bin
, they are not necessarily loaded into the ASP.NET worker process. Instead, only the necessary references are actually loaded.
The main thing to take from this is that the dynamic compilation will indeed do a lot of resolving to help you (after all, you don't even know the name of the dynamic assembly where your types are compiled, so you can't specify it!) - but that doesn't mean that all the assemblies in bin
are loaded in your ASP.NET application domain. The easiest way to check this is to add an empty assembly that isn't referenced anywhere to bin
, and then print out AppDomain.Current.GetAssemblies
- you will see that while the file was indeed touched during the compilation process, it wasn't loaded into the ASP.NET application domain. You need to bear this in mind if you ever try to implement some dynamic module loading in ASP.NET - you need to load those assemblies yourself.
You can tweak the way the compilation works in your web.config (especially the global one) - for example, by default, all the assemblies in bin
are loaded for compilation purposes, but you can use the system.web/compilation/assemblies
tag to cherry pick whatever you want.