private static void AddByConvention(this IServiceCollection serviceCollection, Action <ByConventionConfiguration> options) { if (serviceCollection == null) { throw new ArgumentNullException(nameof(serviceCollection)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var config = new ByConventionConfiguration(); options.Invoke(config); foreach (Assembly assembly in config.Assemblies.Distinct()) { serviceCollection.AddByConvention(assembly, config); } }
private static void AddByConvention(this IServiceCollection serviceCollection, Assembly assembly, ByConventionConfiguration configuration) { if (serviceCollection == null) { throw new ArgumentNullException(nameof(serviceCollection)); } if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } Type[] interfaces = assembly.ExportedTypes .Where(x => x.IsInterface && x.IsPublic && !configuration.IgnoredTypes.Contains(x)) .ToArray(); Type[] classes = assembly.GetTypes() .Where(x => !x.IsInterface && !x.IsAbstract) .ToArray(); foreach (Type @interface in interfaces) { Type[] implementations = classes .Where(@class => @interface.IsAssignableFrom(@class) && @interface.Assembly.Equals(@class.Assembly) && @interface.IsInExactNamespace(@class) && @interface.Name.Equals($"I{@class.Name}")) .ToArray(); if (implementations.Length == 0) { continue; } if (implementations.Length > 1) { continue; } serviceCollection.TryAdd(new ServiceDescriptor(@interface, implementations.First(), configuration.Lifetime)); } }