返回实现通用接口的类的类型

时间:2011-06-10 22:31:40

标签: c# .net

SomeRepository未返回GetPublicClassesFromApplicationAssembly类型。我希望返回所有类型的扩展IRepository的类。有谁能看到这个问题?

  private Type[] GetPublicClassesFromApplicationAssembly()
  {
      return typeof (SomeRepository).Assembly.GetExportedTypes()
            .Where(t => t.IsClass)
            .Where(t => t.IsAbstract == false)
            .Where(r => r.IsAssignableFrom(typeof(IRepository<>)))
            .OrderBy(t => t.Name)
            .ToArray();
  }

  public class SomeRepository : IRepository<SomeDomainClass> {}

  public interface IRepository<T> where T : PrimaryKeyBase {}

  public class SomeDomainClass: PrimaryKeyBase {}

2 个答案:

答案 0 :(得分:5)

SomeRepository无法从IRepository<>分配,而IRepository<SomeDomainClass>不是“真实”类型;它可以从GetInterface分配。您需要使用IsAssignableFrom代替 .Where(r => r.GetInterface("IRepository`1") != null

{{1}}

答案 1 :(得分:4)

如果它有用,这是我为同一目的写的例程:

像这样使用

.Where(r => r.IsDerivedFrom(typeof(IRepository<>)))

这就是

    public static bool IsDerivedFrom(this Type type, Type inter)
    {
        if (type.IsSubclassOf(inter))
            return true;
        if (IsDerivedFromImp(type, inter))
            return true;
        foreach (var i in type.GetInterfaces())
        {
            if (IsDerivedFromImp(i, inter))
                return true;
        }
        return false;
    }

    /// <summary>
    /// type A is equivalent to B if 
    /// 1. They are they same type, AND
    /// 2. Their generic arguments match
    /// </summary>
    /// <param name="iLhs"></param>
    /// <param name="iRhs"></param>
    /// <returns></returns>
    private static bool IsDerivedFromImp(Type iLhs, Type iRhs)
    {
        if (iLhs == iRhs)
        {
            return true;
        }
        if (iLhs.IsGenericType && iRhs.IsGenericType)
        {
            iRhs.GetGenericArguments();
            if (iLhs.GetGenericTypeDefinition() != iRhs.GetGenericTypeDefinition())
            {
                return false;
            }
            // Generic arguments must be match
            var lhsArgs = iLhs.GetGenericArguments();
            var rhsArgs = iRhs.GetGenericArguments();
            for (int x = 0; x < rhsArgs.Length; x++)
            {
                // ie IList<> is derived from IList<>, is true
                if (lhsArgs[x].IsGenericParameter && rhsArgs[x].IsGenericParameter)
                {
                    continue;
                }
                // ie IList<string> is derived from IList<>, is true
                if (!lhsArgs[x].IsGenericParameter && rhsArgs[x].IsGenericParameter)
                {
                    continue;
                }
                // ie IList<> is derived from IList<string>, is false
                if (lhsArgs[x].IsGenericParameter && !rhsArgs[x].IsGenericParameter)
                {
                    return false;
                }
                // ie IDo<string> is derived from IDo<int>, is false
                if (lhsArgs[x] != rhsArgs[x])
                {
                    return false;
                }
            }
            return true;
        }
        return false;
    }