private static ServiceDescriptor GetMetadataServiceDescriptor <T>(Type ImplementationType) { return(ServiceDescriptor.Transient(typeof(Lazy <T, ServiceTypeMetadata>), provider => new Lazy <T, ServiceTypeMetadata>( () => (T)provider.GetRequiredService(ImplementationType), ServiceTypeMetadataExtensions.GetServiceTypeMetadata(ImplementationType) ))); }
public static IServiceCollection AddMetadataDependency(this IServiceCollection services, Func <AssemblyName, bool> predicate = null) { var assemblies = GetAssemblies(predicate); var types = assemblies.SelectMany(i => i.GetExportedTypes()) .Where(t => t.GetTypeInfo() .IsDefined(typeof(ServiceDescriptorAttribute), inherit: true) ); foreach (var type in types) { var typeInfo = type.GetTypeInfo(); var attributes = typeInfo.GetCustomAttributes <ServiceDescriptorAttribute>().ToArray(); // Check if the type has multiple attributes with same ServiceType. var duplicates = attributes .GroupBy(s => s.ServiceType) .SelectMany(grp => grp.Skip(1)); if (duplicates.Any()) { throw new InvalidOperationException($@"Type ""{type.FullName}"" has multiple ServiceDescriptor attributes with the same service type."); } foreach (var attribute in attributes) { var serviceTypes = getRequireMetadataServiceTypes(type, attribute); foreach (var serviceType in serviceTypes) { // var descriptor = new ServiceDescriptor(serviceType, type, attribute.Lifetime); services.Add(descriptor); if (serviceType.IsInterface) { var extensionDescriptor = (ServiceDescriptor)getMetadataServiceDescriptorMethodInfo .MakeGenericMethod(descriptor.ServiceType) .Invoke(null, new object[] { descriptor.ImplementationType }); services.Add(extensionDescriptor); ServiceTypeMetadataExtensions.AddMetadata(descriptor.ImplementationType, attribute.Name); } } } } return(services); }