开发者

Returning types of classes that implement generic interface

The SomeRepository type is not being return by GetPublicClassesFromApplicationAssembly. I want all types of classes extending IRepository to be returned. Can anyone see the problem?

  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 {}


SomeRepository is not assignable from IRepository<>, which is not a "real" type; it's assignable from IRepository<SomeDomainClass>. You need to use GetInterface instead of IsAssignableFrom:

        .Where(r => r.GetInterface("IRepository`1") != null


In case its helpful, here is a routine I wrote for the same purpose:

Use it like this

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

And here it is

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜