I've got a rather large (and growing) application that uses Nancy and subsequently the TinyIoC library. Each of the modules are broken out into individual projects, along with my data models, so my project structure looks sort-of like this:
Solution |- NancyHost |- DataModels |- Modules.Common |- Modules.Dashboard |- Modules.Security |- Repositories
The issue that I'm having is TinyIoC has an AutoRegister
event that is supposed to go through the current AppDomain and register all the "register-able" types. This is great except that on startup the assemblies are not yet loaded into the app domain since it uses DI to resolve types.
As a work-around I've come up with classes like this:
public static class RepositoryInitializer
{
public static void Initialize()
{
}
}
Which I then call from the Main
on startup, but I don't really like that approach since it requires me to make a dummy initializer class for each linked assembly. I could also do something like:
GC.KeepAlive(typeof(ReferencedAssembly.SomeType));
But again, that requires me to add that same directive for each referenced assembly.
I thought I remember something about a hard-binding attribute you could apply to the assembly that would pre-load a referenced assembly? I can't find anything on it but I swear it was there.
I also tried this:
static void Preload()
{
string location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
List<Type> types = new List<Type>();
foreach (var dllFile in Directory.EnumerateFiles(location, "*.dll"))
{
types.AddRange(Assembly.ReflectionOnlyLoadFrom(dllFile).GetTypes());
}
var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
//assemblies does not contain all referenced assemblies
}
Because I read something about using ReflectionOnlyLoadFrom
that would cause the DLL to load, but this gives me an exception about having to preload other referenced DLL's to be able to reflect the types (like System.Core
).
So the question is, how can I preload my referenced assemblies without using explicit references to the types they contain? Please note that Assembly.GetReferencedAssemblies
only contains the loaded assemblies, not all the referenced ones.
This is somewhat duplicate, but not any help: Preload assemblies: referenced, unreferenced, not loaded until they are needed
Edit
Here is a version with Assembly.Load
:
static void Preload()
{
string location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var assemblies = new List<Assembly>();
foreach (var dllFile in Directory.EnumerateFiles(location, "*.dll"))
{
assemblies.Add(Assembly.Load(new AssemblyName() { CodeBase = dllFile }));
//Also tried Assembly.Load(File.ReadAllBytes(dllFile)), same effect
}
var refAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
}
It does load the assemblies into the assemblies
list, but does not cause them to be loaded into the current app domain. (Assembly.GetReferencedAssemblies()
returns the same before and after the Preload
call).