Find Types in All Assemblies

C#.Netasp.netReflectionTypes

C# Problem Overview


I need to look for specific types in all assemblies in a web site or windows app, is there an easy way to do this? Like how the controller factory for ASP.NET MVC looks across all assemblies for controllers.

Thanks.

C# Solutions


Solution 1 - C#

There are two steps to achieve this:

  • The AppDomain.CurrentDomain.GetAssemblies() gives you all assemblies loaded in the current application domain.
  • The Assembly class provides a GetTypes() method to retrieve all types within that particular assembly.

Hence your code might look like this:

foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
    foreach (Type t in a.GetTypes())
    {
        // ... do something with 't' ...
    }
}

To look for specific types (e.g. implementing a given interface, inheriting from a common ancestor or whatever) you'll have to filter-out the results. In case you need to do that on multiple places in your application it's a good idea to build a helper class providing different options. For example, I've commonly applied namespace prefix filters, interface implementation filters, and inheritance filters.

For detailed documentation have a look into MSDN here and here.

Solution 2 - C#

LINQ solution with check to see if the assembly is dynamic:

/// <summary>
/// Looks in all loaded assemblies for the given type.
/// </summary>
/// <param name="fullName">
/// The full name of the type.
/// </param>
/// <returns>
/// The <see cref="Type"/> found; null if not found.
/// </returns>
private static Type FindType(string fullName)
{
    return
        AppDomain.CurrentDomain.GetAssemblies()
            .Where(a => !a.IsDynamic)
            .SelectMany(a => a.GetTypes())
            .FirstOrDefault(t => t.FullName.Equals(fullName));
}

Solution 3 - C#

Easy using Linq:

IEnumerable<Type> types =
            from a in AppDomain.CurrentDomain.GetAssemblies()
            from t in a.GetTypes()
            select t;

foreach(Type t in types)
{
    ...
}

Solution 4 - C#

Most commonly you're only interested in the assemblies that are visible from the outside. Therefor you need to call GetExportedTypes() But besides that a ReflectionTypeLoadException can be thrown. The following code takes care of these situations.

public static IEnumerable<Type> FindTypes(Func<Type, bool> predicate)
{
    if (predicate == null)
        throw new ArgumentNullException(nameof(predicate));

    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
        if (!assembly.IsDynamic)
        {
            Type[] exportedTypes = null;
            try
            {
                exportedTypes = assembly.GetExportedTypes();
            }
            catch (ReflectionTypeLoadException e)
            {
                exportedTypes = e.Types;
            }

            if (exportedTypes != null)
            {
                foreach (var type in exportedTypes)
                {
                    if (predicate(type))
                        yield return type;
                }
            }
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrian MainsView Question on Stackoverflow
Solution 1 - C#Ondrej TucnyView Answer on Stackoverflow
Solution 2 - C#mheymanView Answer on Stackoverflow
Solution 3 - C#Thomas LevesqueView Answer on Stackoverflow
Solution 4 - C#alex.pinoView Answer on Stackoverflow