ASP.NET AddScoped
最后修改于 2025 年 4 月 3 日
在本文中,我们将探讨 ASP.NET 8 中的 AddScoped 方法。此方法对于依赖注入和管理服务生命周期至关重要。
ASP.NET 是一个跨平台、高性能的框架,用于构建现代 Web 应用程序。AddScoped 方法有助于有效管理对象生命周期。
基本定义
AddScoped 是 ASP.NET Core 依赖注入系统中的一个方法。它使用范围生命周期注册一个服务。范围服务在每个客户端请求中创建一次。
使用 AddScoped 时,在单个 HTTP 请求中会共享同一个实例。这对于在请求期间维护状态但不需要在请求之间持久化的服务非常理想。
范围服务在请求结束时被释放。它们通常用于数据库上下文、存储库和其他特定于请求的操作。
ASP.NET AddScoped 示例
以下示例演示了如何将 AddScoped 与存储库模式结合使用。
Program.cs
var builder = WebApplication.CreateBuilder(args); // Register services with different lifetimes builder.Services.AddScoped<IProductRepository, ProductRepository>(); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();
这使用范围存储库服务设置了依赖注入。AddScoped 方法注册了接口-实现对。
Models/Product.cs
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public Product(int id, string name, decimal price)
{
Id = id;
Name = name;
Price = price;
}
}
这个简单的 Product 模型代表了我们的数据结构。它将由我们的存储库和控制器使用。
Repositories/IProductRepository.cs
public interface IProductRepository
{
IEnumerable<Product> GetAll();
Product GetById(int id);
void Add(Product product);
}
该接口定义了我们产品存储库的契约。为了演示目的,它包含了基本的 CRUD 操作。
Repositories/ProductRepository.cs
public class ProductRepository : IProductRepository
{
private readonly List<Product> _products;
private readonly ILogger<ProductRepository> _logger;
public ProductRepository(ILogger<ProductRepository> logger)
{
_logger = logger;
_products = new List<Product>
{
new(1, "Laptop", 999.99m),
new(2, "Mouse", 19.99m),
new(3, "Keyboard", 49.99m)
};
_logger.LogInformation("ProductRepository instance created");
}
public IEnumerable<Product> GetAll() => _products;
public Product GetById(int id) =>
_products.FirstOrDefault(p => p.Id == id);
public void Add(Product product)
{
product.Id = _products.Max(p => p.Id) + 1;
_products.Add(product);
}
}
存储库实现管理我们的产品数据。请注意,它包含了用于日志记录的构造函数注入,展示了 DI 中的 DI。
Controllers/ProductsController.cs
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductRepository _repository;
private readonly ILogger<ProductsController> _logger;
public ProductsController(
IProductRepository repository,
ILogger<ProductsController> logger)
{
_repository = repository;
_logger = logger;
}
[HttpGet]
public IActionResult GetAll()
{
_logger.LogInformation("Getting all products");
return Ok(_repository.GetAll());
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var product = _repository.GetById(id);
if (product == null)
{
_logger.LogWarning("Product {Id} not found", id);
return NotFound();
}
return Ok(product);
}
[HttpPost]
public IActionResult Add([FromBody] Product product)
{
_repository.Add(product);
_logger.LogInformation("Added product {Id}", product.Id);
return CreatedAtAction(nameof(GetById),
new { id = product.Id }, product);
}
}
控制器使用构造函数注入来获取范围存储库。每个请求都会获得自己的存储库实例,确保了适当的隔离。
日志记录演示了每个请求都会创建一个新的存储库。尝试发出多个请求以查看日志消息的实际效果。
此示例展示了 AddScoped 如何提供请求级别的服务实例。存储库在整个请求期间维护其状态,但不会在请求之间泄露。
来源
在本文中,我们探讨了 ASP.NET 8 中的 AddScoped 方法。这项强大的功能有助于在 Web 应用程序中有效管理服务生命周期。