Reputation: 67
I've made up a small test app to demo the issue I'm trying to resolve. I have a plugin architecture where the plugins derive from an interface.
Here's is the interface code:
namespace Test
{
public interface ITestBase
{
int LifeTheUniverseAndEverything();
bool Pessimist();
bool Optimist();
}
}
This builds to a .dll that is referenced by the main program solution and the plugin solution.
Here is the plugin code:
namespace Test
{
public class TestPlugin : ITestBase
{
public int LifeTheUniverseAndEverything() { return 41; }
public bool Pessimist() { return false; }
public bool Optimist() { return true; }
}
}
This produces a .dll that is dropped into a "plugins" folder off the main working directory.
Here's the main program.
namespace Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("testing...");
string[] PluginFileLocs;
try
{
string sWorkingDir = Directory.GetCurrentDirectory();
string sPluginDir = sWorkingDir + "\\Plugins";
PluginFileLocs = Directory.GetFiles(sPluginDir, "*.dll");
foreach (string plugin in PluginFileLocs)
{
Assembly theAssembly = Assembly.ReflectionOnlyLoadFrom(plugin);
foreach (Type type in theAssembly.GetTypes())
{
string aType = type.FullName;
Console.WriteLine(aType);
}
}
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
}
}
}
The issue is, that if the testplugin class derives off the ITestBase interface, the theAssembly.GetTypes throws an exception: unable to load one or more of the requested types. retrieve the LoaderExceptions. Why, and how can I get my plugin to derive off an interface?
Upvotes: 1
Views: 4494
Reputation: 141688
Without further detail, it's hard to tell. My guess would be because you are loading it into a Reflection Only context by using ReflectionOnlyLoadFrom
, which won't resolve dependencies, and the interface and plug ins are in different assemblies, you need to handle the ReflectionOnlyAssemblyResolve
on the AppDomain, or don't load it in a reflection-only context.
Since you are likely to actually load your plug-in and execute them, it may be simplier to just load it completely. Best practice for plug ins is to load them in a different AppDomain and lock it down to keep the plug-in in a sandbox.
Upvotes: 1
Reputation: 684
Based on the documentation for the Assembly.ReflectionOnlyLoadFrom, it will not automatically load dependencies http://msdn.microsoft.com/en-us/library/system.reflection.assembly.reflectiononlyloadfrom.aspx
I'm guessing that's what's going on here. Since your interface is defined in a separate assembly from the plugin, you must first load that assembly before trying to call GetTypes.
Upvotes: 3