From 8e9f7fac3083cac3f412e30075d5f1069c681e69 Mon Sep 17 00:00:00 2001 From: Dan H Date: Wed, 15 Jun 2022 22:32:48 +0100 Subject: [PATCH] Fixing issue where validation was applied to the ServiceDescriptor by the Azure Function Host DI container. --- .../ServiceCollectionExtensions.Decoration.cs | 2 +- src/Scrutor/ServiceDescriptorExtensions.cs | 9 +++++--- test/Scrutor.Tests/DecorationTests.cs | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Scrutor/ServiceCollectionExtensions.Decoration.cs b/src/Scrutor/ServiceCollectionExtensions.Decoration.cs index 55375e5f..f53dfea3 100644 --- a/src/Scrutor/ServiceCollectionExtensions.Decoration.cs +++ b/src/Scrutor/ServiceCollectionExtensions.Decoration.cs @@ -263,7 +263,7 @@ public static bool TryDecorate(this IServiceCollection services, DecorationStrat var decoratedType = new DecoratedType(serviceDescriptor.ServiceType); // Insert decorated - services.Add(serviceDescriptor.WithServiceType(decoratedType)); + services.Add(serviceDescriptor.WithDecoratedType(decoratedType)); // Replace decorator services[i] = serviceDescriptor.WithImplementationFactory(strategy.CreateDecorator(decoratedType)); diff --git a/src/Scrutor/ServiceDescriptorExtensions.cs b/src/Scrutor/ServiceDescriptorExtensions.cs index f734fe1d..dd03bf25 100644 --- a/src/Scrutor/ServiceDescriptorExtensions.cs +++ b/src/Scrutor/ServiceDescriptorExtensions.cs @@ -8,11 +8,14 @@ internal static class ServiceDescriptorExtensions public static ServiceDescriptor WithImplementationFactory(this ServiceDescriptor descriptor, Func implementationFactory) => new(descriptor.ServiceType, implementationFactory, descriptor.Lifetime); - public static ServiceDescriptor WithServiceType(this ServiceDescriptor descriptor, Type serviceType) => descriptor switch + public static ServiceDescriptor WithDecoratedType(this ServiceDescriptor descriptor, DecoratedType serviceType) => descriptor switch { - { ImplementationType: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationType, descriptor.Lifetime), + { ImplementationType: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationType.ToFactory(), descriptor.Lifetime), { ImplementationFactory: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationFactory, descriptor.Lifetime), { ImplementationInstance: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationInstance), _ => throw new ArgumentException($"No implementation factory or instance or type found for {descriptor.ServiceType}.", nameof(descriptor)) - }; + }; + + private static Func ToFactory(this Type serviceType) => + serviceProvider => ActivatorUtilities.CreateInstance(serviceProvider, serviceType); } diff --git a/test/Scrutor.Tests/DecorationTests.cs b/test/Scrutor.Tests/DecorationTests.cs index c75fdc6b..d7317e5a 100644 --- a/test/Scrutor.Tests/DecorationTests.cs +++ b/test/Scrutor.Tests/DecorationTests.cs @@ -229,6 +229,27 @@ public void Issue148_Decorate_IsAbleToDecorateConcreateTypes() Assert.NotNull(inner.Dependency); } + [Fact] + public void Issue171_Decorate_IsAbleToCreateValidRegistration() + { + var services = new ServiceCollection(); + + services + .AddTransient() + .Decorate(); + + foreach (var serviceDescriptor in services) + { + if (serviceDescriptor.ImplementationType != null + && serviceDescriptor.ServiceType != serviceDescriptor.ImplementationType) + { + var implementationTypeInterfaces = serviceDescriptor.ImplementationType.GetInterfaces(); + var implementationAssignableToServiceType = implementationTypeInterfaces.Any(t => t == serviceDescriptor.ServiceType); + Assert.True(implementationAssignableToServiceType); + } + } + } + #region Individual functions tests [Fact]