我已经编写了一个小型测试应用来演示我正在尝试解决的问题。我有一个插件架构,插件派生自一个接口。
这是界面代码:
namespace Test
{
public interface ITestBase
{
int LifeTheUniverseAndEverything();
bool Pessimist();
bool Optimist();
}
}
这构建为主程序解决方案和插件解决方案引用的.dll。
以下是插件代码:
namespace Test
{
public class TestPlugin : ITestBase
{
public int LifeTheUniverseAndEverything() { return 41; }
public bool Pessimist() { return false; }
public bool Optimist() { return true; }
}
}
这会产生一个.dll,它被放入主工作目录下的“plugins”文件夹中。
这是主程序。
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);
}
}
}
}
问题是,如果testplugin类派生出ITestBase接口,则.Assembly.GetTypes会抛出异常:无法加载一个或多个请求的类型。检索LoaderExceptions。为什么,以及如何让我的插件从界面中获取?
答案 0 :(得分:3)
根据Assembly.ReflectionOnlyLoadFrom的文档,它不会自动加载依赖项http://msdn.microsoft.com/en-us/library/system.reflection.assembly.reflectiononlyloadfrom.aspx
我猜这就是这里发生的事情。由于您的接口是在与插件分开的程序集中定义的,因此必须首先加载该程序集,然后再尝试调用GetTypes。
答案 1 :(得分:1)
没有进一步的细节,很难说。我的猜测是因为你使用ReflectionOnlyLoadFrom
将它加载到Reflection Only上下文中,它不会解析依赖关系,并且接口和插件在不同的程序集中,你需要处理ReflectionOnlyAssemblyResolve
在AppDomain上,或者不在仅反射的上下文中加载它。
由于您可能实际加载插件并执行它们,因此完全加载它可能更简单。插件的最佳做法是将它们加载到不同的AppDomain中并将其锁定以将插件保存在沙箱中。