Find Types in All Assemblies

后端 未结 4 1001
南笙
南笙 2020-12-05 06:27

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 acr

相关标签:
4条回答
  • 2020-12-05 06:40

    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));
    }
    
    0 讨论(0)
  • 2020-12-05 06:41

    Easy using Linq:

    IEnumerable<Type> types =
                from a in AppDomain.CurrentDomain.GetAssemblies()
                from t in a.GetTypes()
                select t;
    
    foreach(Type t in types)
    {
        ...
    }
    
    0 讨论(0)
  • 2020-12-05 06:43

    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;
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-05 06:47

    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.

    0 讨论(0)
提交回复
热议问题