liveBook · Manning

ActivatorUtilities

As explained in Pro ASP.NET Core 7, Tenth Edition

ActivatorUtilities is a Microsoft.Extensions.DependencyInjection utility class that creates object instances while resolving constructor dependencies from an IServiceProvider.

ActivatorUtilities, in Microsoft.Extensions.DependencyInjection, creates objects whose constructor dependencies come from an IServiceProvider. It is useful when application code must instantiate a custom class while still honoring dependency injection. section 14.3.2

Use the utility methods for these creation and lookup patterns:

  • CreateInstance<T>(services, args) creates the specified type, resolving service dependencies and accepting optional non-service arguments. section 14.3.2
  • CreateInstance(services, type, args) performs the same operation when the type is supplied at runtime. section 14.3.2
  • GetServiceOrCreateInstance returns an existing registered service or creates an instance when no service is registered. section 14.3.2
  • Do not use ActivatorUtilities to resolve method parameters; resolve per-request endpoint parameters explicitly when request-specific lifetimes matter. section 14.4.2

Activating a route endpoint

Register IResponseFormatter, then create an endpoint instance while mapping a route: `T endpointInstance = ActivatorUtilities.CreateInstance<T>(app.ServiceProvider);` An extension method can inspect the endpoint method with reflection, create a delegate, and map `endpoint/class`. A constructor such as `WeatherEndpoint(IResponseFormatter responseFormatter)` receives the registered formatter automatically. This activation occurs while the application starts; moving the formatter dependency to the request method allows ASP.NET Core to resolve a fresh transient service for every request. section 14.3.2 section 14.4.2

Listing 14.19 The contents of the EndpointExtensions.cs file in the Services folder
using System.Reflection;

namespace Microsoft.AspNetCore.Builder {

   public static class EndpointExtensions {
       public static void MapEndpoint<T>(this IEndpointRouteBuilder app,
               string path, string methodName = "Endpoint") {
                               
           MethodInfo? methodInfo = typeof(T).GetMethod(methodName);
           if (methodInfo?.ReturnType != typeof(Task)) {
               throw new System.Exception("Method cannot be used");
           }
           T endpointInstance =
               ActivatorUtilities.CreateInstance<T>(app.ServiceProvider);
           app.MapGet(path, (RequestDelegate)methodInfo
               .CreateDelegate(typeof(RequestDelegate), 
                   endpointInstance));
       }
   }
}

Inspect the complete MapEndpoint extension, including constructor activation, method validation, reflection, delegate creation, and route registration. section 14.3.2

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Defines four activation methods and demonstrates reflection-based endpoint creation, but does not resolve method parameters.
Examples
Uses WeatherEndpoint, IResponseFormatter, MapEndpoint, reflected delegates, and repeated requests producing different transient GUIDs.
What it assumes
Assumes registered services and an IServiceProvider, while demonstrating constructor dependencies through IResponseFormatter.
What you can do after
Builds custom route extensions that instantiate dependency-injected endpoint classes.
How it connects
Connects dependency injection, IServiceProvider, constructor injection, endpoint routing, reflection, middleware, and transient services.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.