19

Using reflection, How can I get all types that implement some specific interface in .NET Core? I have noticed that the methods usable in .NET 4.6 are not available anymore.

For example, this code doesn't work.

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

It throws The name 'AppDomain' does not exist in the current context error.

7
  • 2
    I'm sure that code works fine, you just don't have an AppDomain. Commented Jul 18, 2016 at 18:15
  • @BlueEyedBehemoth so How to include AppDomain? :D Commented Jul 18, 2016 at 18:16
  • What do you need it for? It's not usually something you mess with. Commented Jul 18, 2016 at 18:20
  • 1
    @BlueEyedBehemoth This is a pretty standard pattern for supporting plugins. Commented Jul 18, 2016 at 19:43
  • 4
    @HansPassant That's not true. People might use Core in environments where they won't port to CoreRT. It is dismissive to assume everyone will be porting their code to CoreRT. Commented Jul 23, 2016 at 2:06

6 Answers 6

21

you can do this way:

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

If you want types in all assemblies, just simply use the following to get all the references and do the above again:)

ass.GetReferencedAssemblies()
Sign up to request clarification or add additional context in comments.

2 Comments

That only gets the types within a single assembly, not all loaded assemblies.
Shorthand using LINQ var types = Assembly.GetEntryAssembly().DefinedTypes.Where(ti => ti.ImplementedInterfaces.Contains(typeof(ILogger))).Select(m => m.FullName);
9

In .NET Core 2.0, you can find all matching types in assemblies that were known at compile time (this does not work for dynamically loaded assemblies) like this:

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

This relies on the Microsoft.Extensions.DependencyModel package.

Comments

9

The full code to get all classes that implement type '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);
            }
        }
    }            
}

Comments

2

As far as I can tell, there is no way to get all loaded assemblies in .Net Core 1.0. It seems a way to do this is planned for 1.1.

Comments

0

A possible solution is tell to interface who are the objects that implement it with [ServiceKnownTypeAttribute] and when you need know the types that implement get by reflexion. Example:

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

And you can recover the types that implemented with:

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

Comments

-1

If you want types in all assemblies, just simply use the following to get all the references and do the above again:)

ass.GetReferencedAssemblies()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.