Dependency injection lets a component declare the service it needs without creating that service or choosing its implementation. In ASP.NET Core, services are registered in Program.cs. When the platform invokes a handler or constructs a component, it resolves declared dependencies and supplies the configured objects. This keeps consumers tied to interfaces rather than implementation classes. section 14.0 section 14.3
A controller that does not choose its repository
HomeController takes an IStoreRepository in its constructor and passes repository.Products to its Index view. Configuration selects EFStoreRepository and creates one for each request. The controller needs no change if another implementation replaces it. A unit test can pass a mock repository directly to the constructor and inspect the products returned to the view. section 7.3.1
Listing 14.15 Using dependency injection in the Program.cs file in the Platform folder
using Platform;
using Platform.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IResponseFormatter,
HtmlResponseFormatter>();
var app = builder.Build();
app.UseMiddleware<WeatherMiddleware>();
app.MapGet("endpoint/class", WeatherEndpoint.Endpoint);
//IResponseFormatter formatter = TypeBroker.Formatter;
app.MapGet("endpoint/function",
async (HttpContext context, IResponseFormatter formatter) => {
await formatter.Format(context,
"Endpoint Function: It is sunny in LA");
});
app.Run();
The Program.cs listing registers IResponseFormatter with AddSingleton, then requests it as a parameter of an endpoint handler. The handler names the interface; registration supplies HtmlResponseFormatter. section 14.3
Choose an access path that fits the component:
- Declare a constructor parameter in a controller, middleware class, or view component. ASP.NET Core inspects it when creating the component. section 7.3.1 section 14.3.1 section 24.3
- Declare a service parameter on a supported endpoint handler. ASP.NET Core resolves it before invoking the handler. section 14.3
- If an intermediary prevents direct injection, use HttpContext.RequestServices and GetRequiredService<T>(); the latter throws if the service is unavailable. ActivatorUtilities can construct a class while resolving its constructor dependencies. section 14.3.2
Registration also controls sharing: singleton services satisfy demands with one object, while transient services are instantiated for each dependency and scoped services for each request. Services may be defined with a type, an object, or a factory. Dependency injection is useful when implementations may change or components need isolated unit tests; for a small, stable project without such tests, its benefit may be limited. section 14.0 section 14.6 section 14.2




















