This is freaking me out, and I'm guessing it's because I'm severely misunderstanding something basic about how assemblies get loaded. I was not expecting this to work, can someone explain why it does?
Projects:
- Plugins has the definition of a plugin class
- Lib1 References Plugins and defines a plugin class
- Lib2 References Plugins and defines a plugin class
- Console references Plugins and looks for dlls near itself to load
Lib1 and Lib2 share a code file via symlink:
namespace Shared
{
public class SharedClass
{
public static string Key { get; set; }
}
}
Lib1 Plugin:
namespace Lib1
{
public class Lib1Plugin : Plugin
{
public override void Load()
{
SharedClass.Key = "Lib1 Key";
Console.WriteLine(SharedClass.Key);
}
public override void Run()
{
Console.WriteLine(SharedClass.Key);
}
}
}
Lib2 Plugin:
namespace Lib2
{
public class Lib2Plugin : Plugin
{
public override void Load()
{
SharedClass.Key = "Lib2 Key";
Console.WriteLine(SharedClass.Key);
}
public override void Run()
{
Console.WriteLine(SharedClass.Key);
}
}
}
Console:
static class Functions
{
public static IEnumerable<Type> FindDerivied(Assembly asm, Type baseType)
{
try
{
return asm.GetTypes().Where(t => baseType.IsAssignableFrom(t) && t != baseType);
}
catch (Exception e)
{
return new List<Type>();
}
}
}
class Program
{
static void Main(string[] args)
{
var di = new DirectoryInfo("Plugins");
var bos = new List<Plugin>();
if (di.Exists)
{
var dlls = di.EnumerateFiles();
foreach (var dll in dlls)
{
var asm = Assembly.LoadFrom(dll.FullName);
var builders = Functions.FindDerivied(asm, typeof(Plugin));
foreach (var builder in builders)
{
var bo = (Plugin)Activator.CreateInstance(builder);
bo.Load();
bos.Add(bo);
}
}
foreach (var bo in bos)
{
bo.Run();
}
var asms = AppDomain.CurrentDomain.GetAssemblies();
foreach (var asm in asms)
{
var exports =
asm.GetExportedTypes().Where(type => type.Name == "SharedClass")
.ToList();
foreach (var export in exports)
{
Console.WriteLine(export.FullName);
}
}
}
}
}
Output:
Lib1 Key
Lib2 Key
Lib1 Key
Lib2 Key
Shared.SharedClass
Shared.SharedClass
How does it know the difference!?