获取在 .NET Core 中实现接口的所有类型

Getting all types that implement an interface in .NET Core

使用反射,如何获取在.NET Core中实现某些特定接口的所有类型?我注意到 .NET 4.6 中可用的方法不再可用。

例如,此代码无效。

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

它抛出 The name 'AppDomain' does not exist in the current context 错误。

据我所知,无法在 .Net Core 1.0 中获取所有加载的程序集。 It seems a way to do this is planned for 1.1.

你可以这样做:

System.Reflection.Assembly ass = System.Reflection.Assembly.GetEntryAssembly();

foreach (System.Reflection.TypeInfo ti in ass.DefinedTypes)
{
    if (ti.ImplementedInterfaces.Contains(typeof(yourInterface)))
    {
        ass.CreateInstance(ti.FullName) as yourInterface;
    }  
}

如果您想要所有程序集中的类型,只需简单地使用以下获取所有引用并再次执行上述操作:)

ass.GetReferencedAssemblies()

如果您想要所有程序集中的类型,只需简单地使用以下获取所有引用并再次执行上述操作:)

ass.GetReferencedAssemblies()

一个可能的解决方案是告诉接口谁是用 [ServiceKnownTypeAttribute] 实现它的对象,以及何时需要知道通过反射实现 get 的类型。示例:

public class TypeWithImplementOne : IMyInterface
{
  public string Hi()
  {
    return "hi";
  }

}
public class TypeWithImplementTwo : IMyInterface
{
   public string Hi()
  {
    return "hi";
  }
}
public interface IMyInterface{
{
  [ServiceKnownType(typeof(TypeWithImplementOne))]
  [ServiceKnownType(typeof(TypeWithImplementTwo))]

  string Hi();
}

并且您可以恢复使用以下方法实现的类型:

private IEnumerable<string> GetKnownTypes()
    {
        List<string> result = new List<string>();

        Type interfaceType = typeof(IMyInterface);
        IEnumerable<CustomAttributeData> attributes = interfaceType.CustomAttributes
            .Where(t => t.AttributeType == typeof(ServiceKnownTypeAttribute));

        foreach (CustomAttributeData attribute in attributes)
        {
            IEnumerable<CustomAttributeTypedArgument> knownTypes = attribute.ConstructorArguments;
            foreach (CustomAttributeTypedArgument knownType in knownTypes)
            {
                result.Add(knownType.Value.ToString());
            }
        }

        result.Sort();
        return result;
    }

获取实现类型 'T'

的所有 类 的完整代码
public static IEnumerable<T> GetAll<T>()
{
    var assembly = Assembly.GetEntryAssembly();
    var assemblies = assembly.GetReferencedAssemblies();

    foreach (var assemblyName in assemblies)
    {
        assembly = Assembly.Load(assemblyName);

        foreach (var ti in assembly.DefinedTypes)
        {
            if (ti.ImplementedInterfaces.Contains(typeof(T)))
            {
                yield return (T)assembly.CreateInstance(ti.FullName);
            }
        }
    }            
}

在 .NET Core 2.0 中,您可以在编译时已知的程序集中找到所有匹配类型(这不适用于动态加载的程序集),如下所示:

private static IEnumerable<Type> GetAllTypesOf<T>()
{
    var platform = Environment.OSVersion.Platform.ToString();
    var runtimeAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(platform);

    return runtimeAssemblyNames
        .Select(Assembly.Load)
        .SelectMany(a => a.ExportedTypes)
        .Where(t => typeof(T).IsAssignableFrom(t));
}

这依赖于 Microsoft.Extensions.DependencyModel 包。