Tomtom
Tomtom

Reputation: 9384

Load Assembly with dependent references

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

Answers (1)

PepitoSh
PepitoSh

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

Related Questions