原文地址:https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-1/
作者:Andrew Lock
译者:Lamond Lu
译文地址:https://www.cnblogs.com/lwqlun/p/10693763.html
回想一下,在你以往编程的过程中,是否经常遇到以下场景:当你从一个服务(Web Api/Database/通用服务)中请求一个实体时,服务响应404, 但是你确信这个实体是存在的。这种问题我已经见过很多次了,有时候它的原因是请求实体时使用了错误的ID。 在本篇博文中,我将描述一种避免此类错误( 原始类型困扰)的方法,并使用C#的类型系统来帮助我们捕获错误。
其实,许多比我厉害的程序员已经讨论过C#中原始类型困扰的问题了。特别是Jimmy Bogard, Mark Seemann, Steve Smith和Vladimir Khorikov编写的一些文章, 以及Martin Fowler的代码重构书籍。最近我正在研究F#, 据我所知,这被认为是一个已解决的问题!
原始类型困扰的一个例子
为了给出一个问题说明,我将使用一个非常基本的例子。假设你有一个电子商务的网站,在这个网站中用户可以下订单。
其中订单拥有以下的简单属性。
public class Order
{
public Guid Id {
get; set; }
public Guid UserId {
get; set; }
public decimal Total {
get; set; }
}
你可以通过OrderService
来创建和读取订单。
public class OrderService
{
private readonly List<Order> _orders = new List<Order>();
public void AddOrder(Order order)
{
_orders.Add(order);
}
public Order GetOrderForUser(Guid orderId, Guid userId)
{
return _orders.FirstOrDefault(
order => order.Id == orderId && order.UserId == userId);
}
}
为了简化代码,这里我们将订单对象保存在内存中,并且只提供了两个方法。
AddOrder()
: 在订单集合中添加订单GetOrderForUser()
: 根据订单Id和用户Id获取订单信息
最后,我们创建一个API控制器,调用这个控制器我们可以创建新订单或者获取一个订单信息。
[Route("api/[controller]")]
[ApiController, Authorize]
public class OrderController : ControllerBase
{
private readonly OrderService _service;
public