/// <summary>
 /// Find and register services from <see cref="IServiceRegistration"/> definitions found, optionally including those not loaded.
 /// </summary>
 /// <param name="services">The services collection.</param>
 /// <param name="startingPoint">Assemblies to start the search from, if not provided the entry assembly is used: Assembly.GetEntryAssembly().</param>
 /// <param name="includeNonPublic">True to include non-public types in the search, otherwise false to search only public types.</param>
 /// <param name="assemblySearchOptions">How to search for additional assemblies to include.</param>
 /// <param name="assemblyNamePrefixes">Case insensitive prefixes of assembly names and file names (*.dlls) to include in search, null/empty to include all.</param>
 public static IServiceCollection AddRegisteredServices(this IServiceCollection services, Assembly startingPoint = null, bool includeNonPublic = false, AssemblySearchOptions assemblySearchOptions = AssemblySearchOptions.Default, bool throwOnError = false, params string[] assemblyNamePrefixes)
 {
Ejemplo n.º 2
0
 /// <summary>
 /// Find all defined types across all referenced assemblies including those in the execution paths.
 /// </summary>
 /// <param name="startingPoint">Assemblies to start the search from, if not provided the entry assembly is used: Assembly.GetEntryAssembly().</param>
 /// <param name="ofType">Type which the results must be assignable to, null for no filter.</param>
 /// <param name="typeFilter">Predicate to filter out returned types, or null for the default which is to include all public instance non-abstract and non-generic classes or value-types.</param>
 /// <param name="mustHavePublicDefaultCtor">True to ensure all returned types have a public default constructor defined, otherwise false.</param>
 /// <param name="assemblySearchOptions">How to search for additional assemblies to include.</param>
 /// <param name="throwOnError">True to throw on any assembly load errors, otherwise false.</param>
 /// <param name="assemblyNamePrefixes">Case insensitive prefixes of assembly names and file names (*.dlls) to include in search, null/empty to include all.</param>
 /// <returns></returns>
 public static IEnumerable <Type> FindAllTypes(Assembly startingPoint = null, Type ofType = null, Predicate <Type> typeFilter = null, bool mustHavePublicDefaultCtor = false, AssemblySearchOptions assemblySearchOptions = AssemblySearchOptions.Default, bool throwOnError = false, IEnumerable <string> assemblyNamePrefixes = null)
 {
     return(FindAssemblies(startingPoint, assemblySearchOptions, throwOnError, assemblyNamePrefixes)
            .SelectMany(a => a.GetLoadableTypes())
            .Where(t => ofType == null || ofType.IsAssignableFrom(t))
            .Where(t => typeFilter?.Invoke(t) ?? ((t.IsClass || t.IsValueType) && t.IsPublic && !t.IsAbstract && !t.IsGenericType))
            .Where(t => !mustHavePublicDefaultCtor || t.IsValueType || t.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null) != null)
            .Distinct() // shouldn't be required
            .ToList());
 }
Ejemplo n.º 3
0
        public static IEnumerable <Assembly> FindAssemblies(Assembly startingPoint = null, AssemblySearchOptions assemblySearchOptions = AssemblySearchOptions.Default, bool throwOnError = false, IEnumerable <string> assemblyNamePrefixes = null)
        {
            var directorySearchOptions = assemblySearchOptions.HasFlagSet(AssemblySearchOptions.IncludeSubdirectories) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
            var matchedAssemblies      = new List <Assembly>();
            var assembliesSearched     = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);

            var assembliesToSearch = new Queue <Assembly>();

            startingPoint ??= Assembly.GetEntryAssembly();
            assembliesToSearch.Enqueue(startingPoint);

            if (assemblySearchOptions.HasFlagSet(AssemblySearchOptions.StartingDirectory))
            {
                assembliesToSearch.EnqueueRange(FindAssemblies(startingPoint, assemblyNamePrefixes, directorySearchOptions, assembliesSearched, throwOnError));
            }

            while (assembliesToSearch.Count > 0)
            {
                var assembly = assembliesToSearch.Dequeue();

                if (assembliesSearched.Add(assembly.FullName))
                {
                    if (!assemblyNamePrefixes.Any() || assemblyNamePrefixes.Any(n => assembly.FullName.StartsWith(n, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        matchedAssemblies.Add(assembly);

                        if (assemblySearchOptions.HasFlagSet(AssemblySearchOptions.ReferencedAssemblies))
                        {
                            assembliesToSearch.EnqueueRange(assembly.GetReferencedAssemblies().Select(a =>
                            {
                                try
                                {
                                    return(Assembly.Load(a));
                                }
                                catch
                                {
                                    if (throwOnError)
                                    {
                                        throw;
                                    }

                                    return(null);
                                }
                            }).WhereNotNull());
                        }

                        if (assembly != startingPoint && assemblySearchOptions.HasFlagSet(AssemblySearchOptions.AssemblyDirectories))
                        {
                            assembliesToSearch.EnqueueRange(FindAssemblies(assembly, assemblyNamePrefixes, directorySearchOptions, assembliesSearched, throwOnError));
                        }
                    }
                }
            }

            return(matchedAssemblies
                   .Distinct() // shouldn't be required
                   .ToList());
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Find all defined types across all referenced assemblies including those in the execution paths.
 /// </summary>
 /// <param name="startingPoint">Assemblies to start the search from, if not provided the entry assembly is used: Assembly.GetEntryAssembly().</param>
 /// <param name="ofType">Type which the results must be assignable to, null for no filter.</param>
 /// <param name="typeFilter">Predicate to filter out returned types, or null for the default which is to include all public instance non-abstract and non-generic classes or value-types.</param>
 /// <param name="mustHavePublicDefaultCtor">True to ensure all returned types have a public default constructor defined, otherwise false.</param>
 /// <param name="assemblySearchOptions">How to search for additional assemblies to include.</param>
 /// <param name="throwOnError">True to throw on any assembly load errors, otherwise false.</param>
 /// <param name="assemblyNamePrefixes">Case insensitive prefixes of assembly names and file names (*.dlls) to include in search, null/empty to include all.</param>
 /// <returns></returns>
 public static IEnumerable <Type> FindAllTypes(Assembly startingPoint = null, Type ofType = null, Predicate <Type> typeFilter = null, bool mustHavePublicDefaultCtor = false, AssemblySearchOptions assemblySearchOptions = AssemblySearchOptions.Default, bool throwOnError = false, params string[] assemblyNamePrefixes)
 {
     return(FindAllTypes(startingPoint, ofType, typeFilter, mustHavePublicDefaultCtor, assemblySearchOptions, throwOnError, (IEnumerable <string>)assemblyNamePrefixes));
 }