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]