使用字符串到接口的GetType

时间:2013-11-20 09:37:46

标签: c# dll interface gettype

我为Control DLL创建了一个DLL加载器(这些控件具有相同的接口iControlPlugin),一切都运行良好。但是我现在需要为设备驱动程序创建一个DLL加载器。我开始查看我的Control Loader代码,并意识到代码是相同的,除非定义了接口类型。因此,我想使我的控制加载器功能更通用,以便它可以用于不同的接口类型。

我修改了函数以便它返回一个字典,我遇到的问题是我检查以确保DLL文件包含匹配的类型,在我的例子中,这是两种接口类型之一。但我总是无效。

这是我原来的工作功能,专门针对一种类型(iLPPControlPlugin)

public Dictionary<string, iLPPControlPlugin> LoadPlugins(string folder)
{
    /* Create a Dictionary object to store the loaded DLL's */
    Dictionary<string, iLPPControlPlugin> plugsins = new Dictionary<string,iLPPControlPlugin>();

    /* Get all the DLL files from the path specified */
    string[] files = Directory.GetFiles(folder, "*.dll");

    /* Go through each DLL... */
    foreach (string file in files)
    {
        /* Load the file, as an assembly. */
        Assembly assembly = Assembly.LoadFile(file);

        /* Get the type, can be more than one */
        var types = assembly.GetExportedTypes();

        /* For each type... */
        foreach (Type type in types)
        {
            if (type.GetInterfaces().Contains(typeof(iLPPControlPlugin)))
            {
                /* Create an instance of the DLL */
                object instance = Activator.CreateInstance(type);

                /* As it is the correct type we know it will contain the "GetControlName" function.
                 * Call this to get the controls name. */
                string controlName = ((iLPPControlPlugin)instance).GetControlName();

                try
                {
                    /* Try to add the instance to the dictionary list, using the control name as the key. */
                    plugsins.Add(controlName, instance as iLPPControlPlugin);
                }
                catch (ArgumentException)
                {
                    /* Fails if there is already a DLL loaded with the same control name. This is a feature
                     * of the dictionary object. */
                    Console.WriteLine("Two or more Dll's have the same control name: " + controlName);
                }
            }
        }
    }
    return plugsins;
}

因此,我已将此功能更改为更通用:

public Dictionary<string, object> LoadPlugins(string folder, string interfaceType)

为了简化问题,我目前忽略参数“interfaceType”并对字符串进行了硬编码,并检查:

Type myType = Type.GetType("PluginInterface.iLPPControlPlugin");
if (type.GetInterfaces().Contains(myType))

但问题是myType始终为null。我尝试了很多不同的变化是没有运气。我确信它会变得简单,但任何人都可以告诉我我做错了什么。有关信息,PluginInterface命名空间和iLPPControlPlugin类是解决方案中的项目。

非常感谢, 克里斯

1 个答案:

答案 0 :(得分:5)

PluginInterface.iLPPControlPlugin类型将无法解析。您必须在PluginInterface.iLPPControlPlugin, MyAssembly的参数中指定程序集名称 Type.GetType()(有关详细信息,请参阅Type.AssemblyQualifiedName)。

Type myType = Type.GetType("PluginInterface.iLPPControlPlugin, MyAssembly");
if (type.GetInterfaces().Contains(myType))

从MSDN了解Type.GetType()

  

如果typeName包含命名空间而不包含程序集名称,则此方法仅按顺序搜索调用对象的程序集和Mscorlib.dll。如果typeName完全使用部分或完整程序集名称限定,则此方法将在指定的程序集中搜索。如果程序集具有强名称,则需要完整的程序集名称。

请注意,您甚至可以仅使用接口名称执行搜索,您必须使用Type.GetInterface()而不是Type.GetInterfaces():它接受一个带有接口名称的字符串参数:

if (type.GetInterface(interfaceType) != null)
{
    // ...
}

请注意,如果您不需要处理具有泛型参数的接口,则此方法非常有效(有关命名约定,请参阅Type.GetInterface()文档)。