private static bool TryDecorateOpenGeneric(this IServiceCollection services, Type serviceType, Type decoratorType, [NotNullWhen(false)] out Exception?error) { var closedGenericServiceTypes = services .Where(x => !x.ServiceType.IsGenericTypeDefinition) .Where(x => HasSameTypeDefinition(x.ServiceType, serviceType)) .Select(x => x.ServiceType) .Distinct() .ToList(); if (closedGenericServiceTypes.Count == 0) { error = new MissingTypeRegistrationException(serviceType); return(false); } foreach (var closedGenericServiceType in closedGenericServiceTypes) { var arguments = closedGenericServiceType.GenericTypeArguments; var closedServiceType = serviceType.MakeGenericType(arguments); var closedDecoratorType = decoratorType.MakeGenericType(arguments); if (!services.TryDecorateDescriptors(closedServiceType, out error, x => x.Decorate(closedDecoratorType))) { return(false); } } error = default; return(true); }
private static bool TryDecorateDescriptors(this IServiceCollection services, Type serviceType, [NotNullWhen(false)] out Exception?error, Func <ServiceDescriptor, ServiceDescriptor> decorator) { if (!services.TryGetDescriptors(serviceType, out var descriptors)) { error = new MissingTypeRegistrationException(serviceType); return(false); } foreach (var descriptor in descriptors) { var index = services.IndexOf(descriptor); // To avoid reordering descriptors, in case a specific order is expected. services[index] = decorator(descriptor); } error = default; return(true); }
/// <summary> /// /// </summary> /// <param name="services"></param> /// <param name="serviceType"></param> /// <param name="error"></param> /// <param name="decorator"></param> /// <returns></returns> private static bool TryDecorateDescriptors(this IServiceCollection services, Type serviceType, [NotNullWhen(false)] out Exception?error, Func <ServiceDescriptor, ServiceDescriptor> decorator) { if (!services.TryGetDescriptors(serviceType, out var descriptors)) { error = new MissingTypeRegistrationException(serviceType); return(false); } foreach (var descriptor in descriptors) { var index = services.IndexOf(descriptor); // 为了避免对描述符重新排序,在需要特定顺序的情况下. services[index] = decorator(descriptor); } error = default; return(true); }