将服务引用传递给另一个服务层是不好的实践吗?

6
我有一个C# MVC应用程序,我按以下方式分解它: 视图 -> 控制器 -> 服务 -> 存储库
我使用瘦控制器的方法,每个视图都有一个唯一的视图模型,该模型从相关服务返回。
快速示例: 视图:/NewAppointment/Step1
其控制器如下所示:
public ActionResult Step1()
{
  return View(_appointmentService.Step1GetModel() );
}

预约服务层看起来会像这样:

public Step1Model Step1GetModel()
{
  return new Step1Model();
}

因此,我在整个应用程序中使用了几个不同的服务层,每个层实现了一个独特的接口。当我需要让一个服务层与另一个服务层交互时,我的问题就出现了。在这种情况下,将接口引用传递给服务调用是否更好,还是应该让控制器处理收集所有数据,然后将相关结果传递回服务?
例如:
假设我想通过默认方式使用客户的信息来填充我的视图模型。我看到有两种方法可以实现这一点:
将客户端接口引用传递给约会服务,然后让约会服务调用客户服务中的适当GetCustomer方法......
代码如下:
 private ICustomerService _customerService;
 private IAppointmentService _appointmentService;

 public ActionResult Step1()
 {
   var viewModel = _appointmentService.Step1GetModel( _customerService );
   return View(viewModel);
 }

或者

让控制器处理获取客户的逻辑,然后将结果传递给预约服务。

代码实现:

private ICustomerService _customerService;
private IAppointmentService _appointmentService;

public ActionResult Step1()
{
    var customer = _customerService.GetCustomer();
    var viewModel = _appointmentService.Step1GetModel( customer );
    return View(viewModel);
}

我对哪种方法更好有些犹豫。第一种方法保持了控制器的简洁,但是在约会服务和客户服务之间创建了一种跨服务的依赖关系。第二种方法将更多的逻辑放到了控制器中,但是保持了服务的完全独立性。

有人认为哪种方法更好吗?

谢谢~

1个回答

7

从概念上讲,我认为你的服务不应该知道你的视图模型,这样做是没有意义的。首先拥有控制器的主要原因之一是将视图逻辑与业务逻辑分离,但如果你的服务返回特定于视图的数据,则它们与你的业务逻辑紧密相连。

理想情况下,我希望方法看起来像这样:

public ActionResult Step1()
{
    var customer = _customerService.GetCustomer();
    var appointment = _appointmentService.GetAppointmentFor(customer);

    var viewModel = new Step1ViewModel(customer, appointment);

    return View(viewModel);
}

为了更直接回答你的问题,我认为你的服务之间互相了解是可以的,因为它们在概念层面上属于同一部分。
另外,还有一件事...
听起来你拥有很多平行的类层次结构,因为你有服务、存储库和控制器等。使用单元工作模式和强大的 ORM 可能更有意义,例如:
public MyController(IUnitOfWork unitOfWork)...

public ActionResult Step1()
{
    var customer = unitOfWork.Find<Customer>();
    var viewModel = new Step1ViewModel(customer.Appointment);
    return View(viewModel);
}

毕竟,您的应用程序的价值在于模型,而不在于服务。

糟糕,误按了回车键。我一直遵循“愚笨”视图模型的原则...大多数情况下它们甚至没有构造函数,也从未有任何方法。然而,以这种方式呈现时,我认为将构造函数添加到其中并使用 AutoMapper 或类似工具获取相关领域层信息是合乎逻辑的。我一直在内部辩论业务与领域映射应该放在哪里,并坚持使用愚笨的视图模型和控制器的想法,我把它们放在了服务中... - TheRightChoyce
这正是automapper所设计的场景。很高兴我能帮上忙。 - jonnii

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接