Reflection.Net: how to load dependencies?
-
05-07-2019 - |
Question
I try to add an addons system to my Windows.Net application using Reflection; but it fails when there is addon with dependencie.
Addon class have to implement an interface 'IAddon' and to have an empty constructor.
Main program load the addon using Reflection:
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\Addon.dll");
Type t = assembly.GetType("Test.MyAddon");
ConstructorInfo ctor = t.GetConstructor(new Type[] { });
IAddon addon= (IAddon) ctor.Invoke(new object[] { });
addon.StartAddon();
It works great when addon do not use dependencie.
But if my addon reference and use an another DLL (C:\Temp\TestAddon\MyTools.dll) that is saved near the addon in disk, it fails:
System.IO.FileNotFoundException: Could not load file or assembly 'MyTools.dll' or one of its dependencies.
I do not wants to copy the addons DLL near my executable, how can i do to tell .Net runtime to search in "C:\Temp\TestAddon\" for any dependency?
Note that adding
Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\MyTools.dll");
do not change anything.
Solution
If MyTools.dll is located in the same directory as Addon.dll, all you need to do is call Assembly.LoadFrom
instead of Assembly.LoadFile
to make your code work. Otherwise, handling the AppDomain.AssemblyResolve
event is the way to go.
OTHER TIPS
Have you looked into using an Inversion Of Control container? I use Castle Windsor with an external Boo file that lets me easily extend the applcation without having to recompile or worry about supplying dependencies
You can use reflection to access the private Assembly.
_GetReferencedAssemblies()
.
Although, the method could change in a future version of the .NET framework, it doesn't seem likely—ASP.NET heavily depends on it, though it's possible they could move it from mscorlib
to System.Web
which is the only assembly that I know of from where the method is referred to.
Assembly.LoadFrom works well until I try to use a webService in my addon, I had had a "Unable to cast object of type 'X' to type 'X'" exception.
It's ugly, but i will use Assembly.LoadFile with the AppDomain.AssemblyResolve.
Thanks guys.
Couple of options:
- You can attach to
AppDomain.AssemblyResolve
to help the CLR resolve the assembly. - You could look into isolating add-ins into their own
AppDomain
(seeSystem.AddIn
namespace and this website).