Lesson 13 of 40 Architecture Advanced 45 min

Dependency Injection & Architecture Patterns

Design maintainable, testable applications using the built-in DI container, clean architecture, vertical slice architecture, and the mediator pattern.

Part 1: Service Lifetimes

LifetimeWhen to UseRegister
TransientLightweight, stateless servicesAddTransient
ScopedPer-request state (e.g., DbContext)AddScoped
SingletonShared app-wide state (e.g., cache)AddSingleton

Part 2: Keyed Services

// Register multiple implementations
builder.Services.AddKeyedSingleton<IPaymentGateway, StripeGateway>("stripe");
builder.Services.AddKeyedSingleton<IPaymentGateway, PayPalGateway>("paypal");

// Inject by key
public CheckoutService([FromKeyedServices("stripe")] IPaymentGateway gateway)

Part 3: MediatR & CQRS

Separate commands (write) from queries (read):
public record CreateOrderCommand(OrderDto Dto) : IRequest<Order>;

public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, Order>
{
  public async Task<Order> Handle(CreateOrderCommand cmd, CancellationToken ct)
  {
    // Business logic here
  }
}

Part 4: Decorator Pattern via DI

// Add caching decorator without modifying original
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.Decorate<IOrderRepository, CachedOrderRepository>();

// Scrutor NuGet package provides .Decorate()
VISUAL STUDIO 2026 MADE EASY
Recommended Book

VISUAL STUDIO 2026 MADE EASY

Build real applications with C#, VB.NET, Python, JavaScript, C++, and .NET 10. A practical companion for mastering Visual Studio 2026 step by step.