How to get all types in the references that implem

2019-06-01 01:22发布

问题:

I have a project contains many references.
I need to find all the types that implement IMyInterface interface.

I tried AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()) but it didn't returned all the types in the references.

How do I do that?

回答1:

I guess the problem might be that some of your referenced assemblies are not currently loaded. You can get all referenced assemblies with GetReferencedAssemblies - but this will only yield the names.

If you want you can go on and load the assemblies with Assembly.Load and inspect them further.

So a possible snippet should be

    var types =
        System.Reflection.Assembly.GetExecutingAssembly()
            .GetReferencedAssemblies()
            .SelectMany(name => Assembly.Load(name).GetTypes())
            .Union(AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()));

to search for the types implementing your interface:

    var withInterfaces =
        types.Where(t => t.GetInterfaces().Any(i => i == typeof(IDisposable)));

If this does not the trick I'm lost as well...



回答2:

You're trying to do this at runtime?

If you just need to know this information generally, and it doesn't have to be at runtime, you can just load up the solution in Visual Studio, then right click on the on the name of the interface in the interface IName { line, and then choose "Find all references" - this should show you all references to the interface in your code.

If it's something you really need at runtime, then see the above answer.



回答3:

using System;
using System.Linq;
using System.Reflection;

// try this for fun:
using IMyInterface=System.Collections.IEnumerable;

namespace TestThat
{
    class MainClass
    {

        public static void Main (string[] args)
        {
            var x = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(a => a.GetTypes())
                .Where(t => typeof(IMyInterface).IsAssignableFrom(t))
                .Where(t => !(t.IsAbstract || t.IsInterface))
                .Except(new [] { typeof(IMyInterface) });

            Console.WriteLine(string.Join("\n", x.Select(y=>y.Name).ToArray()));

        }
    }
}

If looking for derived classes and want to 'skip' the base class:

            .Except(new [] { typeof(MyBaseClass) });

There is your interface detection. I'll have a look why you are not getting all types in references. I'd have expected your code to do that, Brb.