If you’ve ever worked with reflection in .NET, you’re likely familiar with Activator. In .NET 6, ActivatorUtilities was introduced to make it easier to create classes with dependencies. Constructor dependency injection is common in the .NET space, and you’re likely to run into several types that require constructor parameters before being created. The Activator class is a relic of a simpler time, whereas ActivatorUtilities meets developers where .NET is today.

In this post, we’ll look at a code example of how to guide ActivatorUtilities toward the constructor you want to use when building instances of types that may have multiple constructors.

Registering a Type and the Dependencies

Let’s start by looking at a Person class that has a total of three constructors. Wowza!

public class Person(string name, int age = 0)
{
    public Person(string name)
        : this(name, 0)
    {
        Console.WriteLine("Person(string)");
    }
    
    public Person(object name)
        : this(name.ToString()!, 41)
    {
        Console.WriteLine("Person(object)");
    }

    public string Name { get; } = name;
    public int Age { get; } = age;
}

We have the following constructors.

  1. A primary constructor that takes a name and an optional age
  2. A constructor that takes a string dependency
  3. A constructor that takes an object dependency

Let’s set up our new ServiceCollection and add dependencies to the dependency collection. Note that you’ll need to install the NuGet package Microsoft.Extensions.DependencyInjection if you haven’t already.

using Microsoft.Extensions.DependencyInjection;

var collection = new ServiceCollection();

var value = "Khalid";

collection.AddTransient<Person>();
// an instance of object
collection.AddSingleton<object>(value);
// an instance of string
collection.AddSingleton<string>(value);

var serviceProvider = collection.BuildServiceProvider();

var person = ActivatorUtilities.CreateInstance<Person>(serviceProvider);

Console.WriteLine($"{person.Name} is {person.Age} years old.");

Take a second and guess what constructor implementation is called. We’ve satisfied all the dependencies, but just by looking at the code, you can feel a sense of uncertainty creeping in. Let’s run it.

Khalid is 0 years old.

Ah, the primary constructor got called. It makes sense; that’s what “primary” means, right?

What if we want a different constructor to get called?

Using the ActivatorUtilitiesConstructor Attribute

In the Microsoft.Extensions.DependencyInjection package, you’ll find the ActivatorUtilitiesConstructorAttribute. This attribute gives the ServiceProvider hints at which constructor to call first. Let’s modify our Person class definition to call the constructor with the object dependency.

public class Person(string name, int age = 0)
{
    public Person(string name)
        : this(name, 0)
    {
        Console.WriteLine("Person(string)");
    }
    
    [ActivatorUtilitiesConstructor]
    public Person(object name)
        : this(name.ToString()!, 41)
    {
        Console.WriteLine("Person(object)");
    }

    public string Name { get; } = name;
    public int Age { get; } = age;
}

After rerunning our code, we’ll get the following output:

Person(object)
Khalid is 41 years old.

Note that we did not change the executing code; we only added a single attribute. With this knowledge, you can now have all the constructors you want on your types but still make it clear which constructor you’d like ActivatorUtilities to use.

There you have it. I hope you enjoyed this post. As always, thanks for reading and sharing with friends and colleagues. Cheers.