从加载的程序集中查找实现接口的对象 - 如何比较类型? [英] Finding objects that implement interface from loaded assembly -how to compare types?

查看:121
本文介绍了从加载的程序集中查找实现接口的对象 - 如何比较类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它将加载目录中的所有程序集,然后让所有类型看到它们是否实现了一个接口。
我无法进行类型比较。在调试器中,如果总是未通过比较,我会看到我的类型已加载(我感兴趣的那个)。如果我在本地使用相同的比较代码,我没有问题,我得到了预期的结果。我可以在类型接口上进行sting比较,但我更愿意知道我做错了什么。

I have class that will load all assemblies in a directory and then get all the types an see if they implement an interface. I cannot get the type comparison to work. In the debugger I see my type loaded (the one I am interested in) if always fails the comparison. If I use the same comparison code locally there is no problem I get the expected result. I could just do sting compares on the type interfaces, but I'd prefer to know what I am doing wrong.

测试:

    // Fails
    [Fact]
    public void FindISerialPortTest()
    {
        var path = Directory.GetCurrentDirectory();
        var results = FindImplementers.GetInterfaceImplementor<ISerialPort>(path);
        results.Length.Should().Be(1);
        results[0].Should().BeAssignableTo<SerialPortWrapper>();
    }

    //Passes
    [Fact]
    public void DoesTypeImplementInterfaceTest()
    {
        var myType = typeof(SerialPortWrapper);
        var myInterface = typeof(ISerialPort);
        FindImplementers.DoesTypeImplementInterface(myType, myInterface).Should().Be(true);

    }

班级:

    public class FindImplementers
{

    public static T[] GetInterfaceImplementor<T>(string directory)
    {
        if (String.IsNullOrEmpty(directory)) { return null; } //sanity check

        DirectoryInfo info = new DirectoryInfo(directory);
        if (!info.Exists) { return null; } //make sure directory exists

        var implementors = new List<T>();

        foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory
        {
            Assembly currentAssembly = null;
            Type[] types = null;
            try
            {
                //using Reflection, load Assembly into memory from disk
                currentAssembly = Assembly.LoadFile(file.FullName);
                types = currentAssembly.GetTypes();
            }
            catch (Exception ex)
            {
                //ignore errors
                continue;
            }

            foreach (Type type in types)
            {
                if (!DoesTypeImplementInterface(type, typeof(T)))
                {
                    continue;
                }
                //Create instance of class that implements T and cast it to type
                var plugin = (T)Activator.CreateInstance(type);
                implementors.Add(plugin);
            }
        }
        return implementors.ToArray();
    }

    public static bool DoesTypeImplementInterface(Type type, Type interfaceType)
    {
        return (type != interfaceType && interfaceType.IsAssignableFrom(type));
    }

}


推荐答案

好的 - 这给了我答案:
invalidcastexception-when-using-assembly-loadfile

OK - this gave me the answer: invalidcastexception-when-using-assembly-loadfile

这是更新的类:

public class PluginLoader
{
    public static T[] GetInterfaceImplementor<T>(string directory)
    {
        if (String.IsNullOrEmpty(directory)) { return null; } //sanity check

        DirectoryInfo info = new DirectoryInfo(directory);
        if (!info.Exists) { return null; } //make sure directory exists

        var implementors = new List<T>();

        foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory
        {
            Assembly currentAssembly = null;
            try
            {
                var name = AssemblyName.GetAssemblyName(file.FullName);
                currentAssembly = Assembly.Load(name);
            }
            catch (Exception ex)
            {
                continue;
            }

            currentAssembly.GetTypes()
                .Where(t => t != typeof(T) && typeof(T).IsAssignableFrom(t))
                .ToList()
                .ForEach(x => implementors.Add((T)Activator.CreateInstance(x)));
        }
        return implementors.ToArray();
    }
}

这篇关于从加载的程序集中查找实现接口的对象 - 如何比较类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆