views:

418

answers:

3

My projects are set up like this:

  • Project "Definition"
  • Project "Implementation"
  • Project "Consumer"

Project "Consumer" references both "Definition" and "Implementation", but does not statically reference any types in "Implementation".

When the application starts, Project "Consumer" calls a static method in "Definition", which needs to find types in "Implementation"

Is there a way I can force any referenced assembly to be loaded into the App Domain without knowing the path or name, and preferably without having to use a full-fledged IOC framework?

+1  A: 

You can use Assembly.GetReferencedAssemblies to get an AssemblyName[], and then call Assembly.Load(AssemblyName) on each of them. You'll need to recurse, of course - but preferably keeping track of assemblies you've already loaded :)

Jon Skeet
I found that, but the problem is that I have to do whatever I'm doing from the referenced assembly... and at least in the context of a unit test, GetCallingAssembly, GetExecutingAssembly of course return the referenced assembly, and GetEntryAssembly returns null :\
Daniel Schaffer
I just realized that I explained my question very badly... it's reworded now
Daniel Schaffer
If you are after loading reference assemblies then the above will solve your problem. You can also ask a specific type typeof(T).Assembly if that helps. I have a feeling that what you need is to dynamically load the assemblies that contain the implementation (not referenced). If this is the case, you will have to either keep a static list of name and load them manually or going through your entire directory, load and then find the type with the right interfaces.
Fadrian Sudaman
+2  A: 

This seemed to do the trick:

        var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
        var loadedPaths = loadedAssemblies.Select(a => a.Location).ToArray();

        var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");
        var toLoad = referencedPaths.Where(r => !loadedPaths.Contains(r, StringComparer.InvariantCultureIgnoreCase)).ToList();
        toLoad.ForEach(path => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(path))));

As Jon noted, the ideal solution would need to recurse into the dependencies for each of the loaded assemblies, but in my specific scenario I don't have to worry about it.

Daniel Schaffer
A: 

Daniel's example code here is excellent. Perfect solution for forcing assemblies referenced in Solution Explorer but not loaded by .Net runtime to be loaded. After this code has run, all assemblies are returned by AppDomain.CurrentDomain.GetAssemblies(). Beautiful stuff! (I gotta start using Linq more...)

john_30
My lack of a reputation score doesn't allow me to comment directly on Daniel's answer above. Sorry about that!
john_30