Skip to content

ActivatorUtilitiesConstructorAttribute Does Not Work in Some Cases #42339

Description

@lawrence-laz

Describe the bug

ActivatorUtilities.CreateInstance<T>(IServiceProvider provider, params object[] parameters) does not respect ActivatorUtilitiesConstructorAttribute in a case when constructor ordering is changed.

To Reproduce

Steps to reproduce the behavior:

  1. Using version '3.1.6' of package 'Microsoft.Extensions.DependencyInjection'
  2. Run this test code:
    using Microsoft.Extensions.DependencyInjection;
    using System;
    using Xunit;
    
    namespace UnitTests
    {
        public class ActivatorUtilitiesConstructorTests
        {
            public class Dependency1 { }
            public class Dependency2 { }
            public class Dependency3 { }
    
            public class Service1
            {
                public Service1(Dependency1 dependency1, Dependency3 dependency3)
                {
                    throw new Exception("This should not be called.");
                }
    
                [ActivatorUtilitiesConstructor]
                public Service1(Dependency1 dependency1, Dependency2 dependency2, Dependency3 dependency3)
                {
                }
            }
    
            public class Service2
            {
                [ActivatorUtilitiesConstructor]
                public Service2(Dependency1 dependency1, Dependency2 dependency2, Dependency3 dependency3)
                {
                }
    
                public Service2(Dependency1 dependency1, Dependency3 dependency3)
                {
                    throw new Exception("This should not be called.");
                }
            }
    
            [Fact]
            public void CreateInstance_WithActivatorUtilitiesConstructorBeingSecond_ShouldChooseMarkedCtor()
            {
                // Arrange
                var dependency1 = new Dependency1();
                var dependency3 = new Dependency3();
    
                var provider = new ServiceCollection()
                    .AddScoped<Dependency2>()
                    .BuildServiceProvider();
    
                // Act & Assert
                ActivatorUtilities.CreateInstance<Service1>(provider, dependency1, dependency3); // This works.
            }
    
            [Fact]
            public void CreateInstance_WithActivatorUtilitiesConstructorBeingFirst_ShouldChooseMarkedCtor()
            {
                // Arrange
                var dependency1 = new Dependency1();
                var dependency3 = new Dependency3();
    
                var provider = new ServiceCollection()
                    .AddScoped<Dependency2>()
                    .BuildServiceProvider();
    
                // Act & Assert
                ActivatorUtilities.CreateInstance<Service2>(provider, dependency1, dependency3); // This fails.
            }
        }
    }
  3. See error This should not be called. when constructor marked with ActivatorUtilitiesConstructorAttribute is defined first, but no error when it is defined second.

Expected behavior

I expect ActivatorUtilitiesConstructorAttribute to be respected regardless of the order in which constructors were defined.

Additional context

The given example is reproduced using 3 dependencies. Removing one dependency makes both tests pass. Maybe this will help to get on a right path.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions