2011-06-10 8 views
1

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

答えて

5

SomeRepository「本物」タイプではありませんこれは、IRepository<>から割り当て可能ではありません。それはIRepository<SomeDomainClass>から割り当てることができます。ここでは、その有用私は同じ目的のために書いたルーチンがある場合は

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

:あなたはGetInterfaceの代わりIsAssignableFromを使用する必要が

この

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

を、それを使用して、ここ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; 
    } 
関連する問題