【问题标题】:Using reflection to find all classes in an assembly that contain an interface by name使用反射在程序集中查找包含名称的接口的所有类
【发布时间】:2014-01-06 17:45:36
【问题描述】:

我正在研究 Apache Thrift 的实现,thrift 生成的所有服务类都包含一个名为 Iface 的嵌套接口。

我有一些额外的代码,它们采用 thrift 生成的内容并根据命名约定构建页面对象模式。

我需要做的是,使用反射枚举生成的程序集中所有具有名为 Iface 的嵌套接口的类。

所有这些代码之前都是使用 protobuf.net 和 Google 协议缓冲区实现的,我们正在切换以实现更一致的多语言支持。

通过 protobuf 实现,我们使用这一行来查找正确的服务:

_inputDll.GetTypes().Where(x => typeof(IService).IsAssignableFrom(x) && x.Name != "Stub")

这种结构不再起作用,因为 thrift 中没有一个确定接口。

这是我尝试搜索的 Thrift 生成代码示例:

 public partial class ServiceA {
    public interface Iface {
      Thrift.ActionResult SetupPreferences(Thrift.BillingPreferencesInfo info);
    }
    // Thrift implementations
}

 public partial class ServiceB {
    public interface Iface {
      Thrift.ActionResult SetupAddress(Thrift.AddressInfo info);
    }
    // Thrift implementations
}

【问题讨论】:

  • 特别是对于这个实现,我没有尝试过任何东西,因为我不知道如何继续,因为这是多个不同的接口,我无权获取类型,我将添加一个问题的更多细节。
  • “嵌套接口”是指类范围内的接口声明,还是使用“嵌套”一词而不是“实现”?你最好提供一个示例类。
  • 不,我的意思是在类中声明的接口。这是我遇到的节俭的一个缺点。
  • 我还在尝试找出你想要达到的目标?背后的想法是什么?特别是,为什么要使用反射来查找特定的 Thrift 接口?
  • thrift 实现用于 Ui 自动化测试,根据我们在 thrift 中定义的服务名称,我们有一些代码可以生成额外的代码来创建页面对象模式或状态机。因此,编写测试的人无需了解所有服务以及每个时刻可能执行的操作。

标签: c# reflection thrift


【解决方案1】:

如果源类如下所示:

public class SomeClass
{
    public interface IFace { … }
}

那么你的查询需要使用Type.GetNestedType(),像这样:

someAssembly.GetTypes().Where(t => t.IsClass && t.GetNestedType("Iface") != null)

【讨论】:

  • 太棒了,乍一看这应该可行,一旦我测试它就会接受。谢谢。
【解决方案2】:

试试这个,代码有点旧,但可以:

public static System.Collections.Generic.List<Type> GetTypesImplementingInterface(string interfaceTypeName, string assembliesNameStartWith)
    {
        var returnTypes = new System.Collections.Generic.List<Type>();

        var list = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(referencedAssembly => referencedAssembly.FullName.StartsWith(assembliesNameStartWith, StringComparison.InvariantCultureIgnoreCase)).ToList();

        try
        {
            returnTypes.AddRange(
                from ass in list
                from t in ass.GetTypes()
                where (TypeImplementsInterface(t, interfaceTypeName))
                select t
            );
        }
        catch (Exception ex)
        {
            Trace.TraceWarning("GetTypesImplementingInterface:{0}:interfaceTypeName:{1}:assembliesNameStartWith:{2}",
                               ex.ToString(), interfaceTypeName, assembliesNameStartWith);
            returnTypes = new System.Collections.Generic.List<Type>();
        }
        return returnTypes;
    }


    private static bool TypeImplementsInterface(Type theType, string interfaceName)
    {
        Type interFaceType = theType.GetInterface(interfaceName, true);
        return (interFaceType != null);
    }

【讨论】:

  • 问题是我要找的类没有实现任何接口
  • from t in ass.GetTypes()... 这真正返回了什么? :)
  • 装配中的类型或赃物的类型:P
猜你喜欢
  • 2010-11-23
  • 2010-12-05
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 2020-10-01
相关资源
最近更新 更多