使用反射按名称查找包含接口的程序集中的所有类

时间:2014-01-06 17:45:36

标签: c# reflection thrift

我正在开发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
}

2 个答案:

答案 0 :(得分:1)

如果源类看起来像这样:

public class SomeClass
{
    public interface IFace { … }
}

然后您的查询需要使用Type.GetNestedType(),如下所示:

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

答案 1 :(得分:0)

试试这个,这是一个有点旧的代码,但它的工作原理:

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);
    }