我有一个在控制器中使用的OrderService。
我所做的只是从自定义控制器继承,我将OrderService作为属性添加。我在OnActionExecuting事件中初始化OrderService。
初始化OrderService时,我设置了Order属性。
这是因为OrderService对Order执行操作,因此将其设置一次而不必将Order传递给每个方法都是有意义的。
此设计是否遵循良好做法?
public class MyController : Controller
{
public OrderService OrderService {get; set;}
protected override void OnActionExecuting(...)
{
OrderService = new OrderService(getOrderIdFromCookie());
}
}
public class OrderService
{
private Order _order;
public OrderService(int orderId)
{
_order = Dao.GetOrderById(orderId);
}
public void AddProduct(Product product)
{
product.OrderId = _order.Id; // assumes order is loaded
ProductDao.Add(product);
}
}
这实际上是一个与语言无关的问题,据我所知,服务不应该包含任何类型的任何状态。
我认为服务层类应该是单身正确吗? (使用依赖注入进行设置时)。
方法不应假设Order对象具有状态。
如果是这种情况,那么我的设计是不正确的?
答案 0 :(得分:2)
服务层不应该是单身人士。
它也不应包含对象状态。
服务层应该能够在其类型的任何实例上运行,而不是存储单个实例......这导致必须创建多个服务实例以处理多个订单。例如:
public interface IOrderService
{
public void AddProduct(Order order, Product product);
}
public class DaoOrderService : IOrderService
{
public Order GetOrder(orderId)
{
return Dao.GetOrderById(orderId);
}
public void AddProduct(Order order, Product product)
{
// The way this method works seems like it should be in a ProductService
// rather than in the OrderService.
product.OrderId = _order.Id;
ProductDao.Add(product);
}
}
然后你的控制器会有类似的东西:
public class MyController : Controller
{
public IOrderService OrderService { get; private set; }
public MyController(IOrderService orderService)
{
OrderService = orderService ?? new DaoOrderService();
}
public MyController()
: this(null)
{ }
protected override void OnActionExecuting(...)
{
Order myOrder = OrderService.GetOrder(orderId);
// Some stuff here
orderService.AddProduct(myOrder, selectedProduct);
}
}
答案 1 :(得分:1)
市场上的大多数ORM产品采用不同的方法,我倾向于认为这是一种更好的做法,即遍历对象图持续变化。
这意味着而不是
public void AddProduct(Product product)
{
product.OrderId = _order.Id; // assumes order is loaded
ProductDao.Add(product);
}
你这样做:
myOrder.Products.Add(product);
Service.Save(myOrder);
答案 2 :(得分:0)
我认为服务通常是我喜欢随时调用的一组方法。根据我的理解,服务始终存在,我不必创建一个。虽然有些用例可以通过服务工厂来实现。
所以我的观点是,服务应该是无状态的 - 至少从用户的角度来看。它可以保留一些由服务提供商维护或设置的一般状态,但从用户的角度来看,它应该像单身一样显示。
不能说它是正确还是不正确的设计,但我会避免有状态或参数化的服务(或以不同的方式调用各种类)
答案 3 :(得分:0)
你的方法在你描述的方式上有些不同寻常是正确的。
当代智慧表明“服务层”或“服务类”不保持状态 - 它将接受所有输入(包括订单)作为其API函数的参数。但是(fwiw)您的服务似乎只是一个内存中的.NET对象 - 而不是WebService或EJB或其他基于网络的服务。实际上你根本不需要把它称为“服务”。
您的对象可能是'OrderProcessor',或者甚至更好(也许),您可以将服务类与订单类本身结合起来。
我希望我能提供一个更完整的描述,以及一个可靠的推荐,但很难(对我而言)仅仅看一对接口是非常自以为是。您提到的实践模式是为了在某些情况下提供优势而创建的。如果我不知道你的情况究竟是什么,那么声称知道“正确”的答案基本上是Cargo Cult Programming。