简体   繁体   中英

C# cast a class to an Interface List

I'm trying to load some .dll files dynamically. The Files are Plugins (self-written for now) which have at least one class that implements MyInterface . For each file I'm doing the following:

    Dictionary<MyInterface, bool> _myList;

    // ...code

    Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        var myI = type.GetInterface("MyInterface");
        if(myI != null)
        {
            if ((myI.Name == "MyInterface") && !type.IsAbstract)
            {
                var p = Activator.CreateInstance(type);
                _myList.Add((MyInterface)p, true);
            }
        }
    }

Running this causes a cast exception, but I can't find a workaround. Anyway I am wondering why this doesn't work at all. I'm looking for a solution in .NET Framework 3.5.

Another thing that happened to me was getting null in p after running the following at the point before adding a new entry to _myList in the code above:

var p = type.InvokeMember(null, BindingFlags.CreateInstance, null,
                          null, null) as MyInterface;

This code was the first attempt on loading the plugins, I didn't find out why p was null yet. I hope someone can lead me to the right way :)

There's much easier way to check if your type can be casted to your interface.

Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
foreach (Type type in assembly.GetTypes())
{
    if(!typeof(MyInterface).IsAssignableFrom(type))
        continue;

    var p = Activator.CreateInstance(type);
    _myList.Add((MyInterface)p, true);
}

If IsAssignableFrom is false, there's something wrong with your inheritance, which is most likely cause of your errors.

您应该真正阅读插件并通过Jon Skeet强制转换异常 ,它解释了您看到的行为以及如何正确地执行插件框架。

Please look into the following code. I think Type.IsAssignableFrom(Type type) can help you out in this situation.

Assembly assembly = Assembly.LoadFrom(currentFile.FullName);
///Get all the types defined in selected  file
Type[] types = assembly.GetTypes();

///check if we have a compatible type defined in chosen  file?
Type compatibleType = types.SingleOrDefault(x => typeof(MyInterface).IsAssignableFrom(x));

if (compatibleType != null)
{
    ///if the compatible type exists then we can proceed and create an instance of a platform
    found = true;
    //create an instance here
    MyInterface obj = (ALPlatform)AreateInstance(compatibleType);

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM