Reputation: 9384
In my application I have an interface
called IPlugin
. This interface
is used to identify dlls in a Plugin-folder and load them at application-startup.
The IPlugin
interface looks like:
public interface IPlugin
{
string Name { get; }
void Initialize();
}
In my main-application I've used the following code to load all dll-files which are located in the Plugins-folder:
internal List<IPlugin> LoadPlugins()
{
List<IPlugin> plugins = new List<IPlugin>();
foreach (string file in Directory.GetFiles("Plugins", "*.dll", SearchOption.TopDirectoryOnly))
{
Assembly assembly = Assembly.LoadFile(Path.GetFullPath(file));
Type targetType = assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IPlugin)));
if (targetType != null)
{
IPlugin plugin = Activator.CreateInstance(targetType) as IPlugin;
if (plugin != null)
{
plugins.Add(plugin);
}
}
}
return plugins;
}
This just works fine for dlls which don't need another dll.
Now I've created a plugin which has two dlls.
Users.Plugin has a references to Users.Interface. In the Users.Plugin there is an implementation of IPlugin
. So the Users.Plugin-Dll will be identified to be loaded by my LoadPlugins-Method.
Now I get a ReflectionTypeLoadException
with the Users.Plugin-File at the line:
Type targetType = assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IPlugin)));
The LoaderException tells me, that the assembly Users.Interface or a reference could not be found.
I've tried to use Assembly.LoadFrom(...)
but this doesn't work either.
I've also tried this approach with no success.
Any ideas how I can load assemblies with all dependencies and then create an instance?
Upvotes: 2
Views: 566
Reputation: 1836
A code snippet to resolve assemblies at runtime:
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
String DllName = new AssemblyName(args.Name).Name + ".dll";
return Assembly.LoadFile(DllName);
}
Set it at the beginning of your your plugin initializer:
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
No error checking is included.
The actual assembly can be loaded from any path, the example above loads it from the current working directory. You can load it from embedded resource as well.
Upvotes: 2