我正在应用程序中实现一个简单的插件架构。插件要求是使用接口(IPlugin)定义的,该接口位于应用程序和插件引用的* .dll中。该应用程序有一个插件管理器(也在同一个* .dll中),它通过在插件文件夹中查找所有* .dll来加载插件,加载它们,然后检查插件是否实现了接口。我已经通过两种不同的方式检查了[以前通过一个简单的if(插件是IPlugin)],但是当插件实现接口时,都不会识别。这是代码:
Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
foreach (Type currType in pluginAssembly.GetTypes())
{
if (currType.GetInterfaces().Contains(typeof(IPlugin)))
{
// Code here is never executing
// even when the currType derives from IPlugin
}
}
}
我曾经测试过一个特定的类名(“插件”),但后来我允许它循环遍历程序集中的所有类都无济于事。 (这是我在其他地方找到的一个例子。) 为了使这更复杂,有两个接口,每个接口实现原始接口(IPluginA,IPluginB)。该插件实际上实现了一个更具体的接口(IPluginB)。但是,我尝试使用插件只是实现了更通用的接口(IPlugin),但这仍然不起作用。
[编辑:回应我第一次收到的两个回复] 是的,我尝试过使用IsAssignableFrom。请参阅以下内容:
Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
foreach (Type currType in pluginAssembly.GetTypes())
{
if (typeof(IPlugin).IsAssignableFrom(currType))
{
string test = "test";
}
}
}
答案 0 :(得分:5)
你试过了吗?
typeof(IPlugin).IsAssignableFrom(currType)
此外,类型实现接口,但它们不从派生。 BaseType
属性和IsSubclassOf
方法显示派生,IsAssignableFrom
显示派生或实现。
编辑:您的程序集是否已签名?它们可能正在加载side-by-side versions of your assembly,并且由于Type
个对象与ReferenceEquals
进行比较,因此两个并排程序集中的相同类型将完全独立。
编辑2 :试试这个:
public Type[] LoadPluginsInAssembly(Assembly otherAssembly)
{
List<Type> pluginTypes = new List<Type>();
foreach (Type type in otherAssembly.GetTypes())
{
// This is just a diagnostic. IsAssignableFrom is what you'll use once
// you find the problem.
Type otherInterfaceType =
type.GetInterfaces()
.Where(interfaceType => interfaceType.Name.Equals(typeof(IPlugin).Name, StringComparison.Ordinal)).FirstOrDefault();
if (otherInterfaceType != null)
{
if (otherInterfaceType == typeof(IPlugin))
{
pluginTypes.Add(type);
}
else
{
Console.WriteLine("Duplicate IPlugin types found:");
Console.WriteLine(" " + typeof(IPlugin).AssemblyQualifiedName);
Console.WriteLine(" " + otherInterfaceType.AssemblyQualifiedName);
}
}
}
if (pluginTypes.Count == 0)
return Type.EmptyTypes;
return pluginTypes.ToArray();
}
答案 1 :(得分:2)
您正在寻找IsAssignableFrom方法:
Type intType = typeof(IInterface);
foreach (Type t in pluginAssembly.GetTypes())
{
if (intType.IsAssignableFrom(t))
{
}
}