Dependency Injection in Razor Pages

Advanced 25 min read Lesson 7 of 8

What is Dependency Injection?

Dependency Injection (DI) is a design pattern where objects receive their dependencies from an external source rather than creating them internally.

Registering Services

// Program.cs
builder.Services.AddScoped<IProductService, ProductService>();
builder.Services.AddScoped<ICategoryService, CategoryService>();
builder.Services.AddTransient<IEmailService, EmailService>();
builder.Services.AddSingleton<ILogger, Logger>();

Service Lifetimes

Transient

New instance every time it's requested

builder.Services.AddTransient<IEmailService, EmailService>();

Scoped

One instance per request/scope

builder.Services.AddScoped<IProductService, ProductService>();

Singleton

One instance for the entire application lifetime

builder.Services.AddSingleton<IConfiguration, Configuration>();

Using DI in PageModel

Constructor Injection

public class IndexModel : PageModel
{
    private readonly IProductService _productService;
    private readonly ILogger<IndexModel> _logger;
    
    public IndexModel(IProductService productService, ILogger<IndexModel> logger)
    {
        _productService = productService;
        _logger = logger;
    }
    
    public async Task OnGetAsync()
    {
        _logger.LogInformation("Loading products...");
        Products = await _productService.GetProductsAsync();
    }
}

Property Injection

[Inject]
public IProductService ProductService { get; set; }

Custom Services Example

// Services/Interfaces/IProductService.cs
public interface IProductService
{
    Task<List<Product>> GetProductsAsync();
    Task<Product> GetProductByIdAsync(int id);
    Task<Product> CreateProductAsync(Product product);
}

// Services/Implementations/ProductService.cs
public class ProductService : IProductService
{
    private readonly ApplicationDbContext _context;
    
    public ProductService(ApplicationDbContext context)
    {
        _context = context;
    }
    
    public async Task<List<Product>> GetProductsAsync()
    {
        return await _context.Products.ToListAsync();
    }
}
Key Takeaway

Dependency Injection promotes loose coupling, testability, and maintainable code.

Test Your Knowledge - Take Quiz