Вопрос

I have created a DLL loader for Control DLL's (these controls have the same interface iControlPlugin), all is working great. However I now need to create a DLL loader for device drivers. I started looking at my Control Loader code and realised that the code is identical, except where the interface type is defined. I would therefore like to make my control loader function more generic so that it can be used for different interface types.

I have modified the function so that it returns a dictionary, the problem I am having is that I do a check to make sure that the DLL file contains a matching type, in my case this is one of two interface types. But I always get null.

This is my original, working function which is specifically targeted at one type (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;
}

I have therefore changed the function, to be more generic, to this:

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

To simplify the problem I currently ignore the parameter "interfaceType" and have hard coded the string, and check to this:

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

However the problem is that myType is always null. I have tried many different variations is no luck. I'm sure its going to be something simple but can anyone tell me what I am doing wrong. For information the PluginInterface namespace and iLPPControlPlugin class is a project within the solution.

Many thanks, Chris

Это было полезно?

Решение

With PluginInterface.iLPPControlPlugin type won't be resolved. You have to specify assembly name too PluginInterface.iLPPControlPlugin, MyAssembly in the parameter of Type.GetType() (see Type.AssemblyQualifiedName for further details).

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

From MSDN about Type.GetType():

If typeName includes the namespace but not the assembly name, this method searches only the calling object's assembly and Mscorlib.dll, in that order. If typeName is fully qualified with the partial or complete assembly name, this method searches in the specified assembly. If the assembly has a strong name, a complete assembly name is required.

Please note that you may even perform your search with interface name only, you have to use Type.GetInterface() instead of Type.GetInterfaces(): it accepts one single string parameter with interface name:

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

Note this works pretty well if you don't need to handle interfaces with generic parameters (see Type.GetInterface() documentation for naming conventions).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top