【问题标题】:Is passing a service reference to another service layer bad practice?将服务引用传递给另一个服务层是不好的做法吗?
【发布时间】:2011-05-18 02:40:58
【问题描述】:

我有一个 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);
}

我不知道哪种做法更好。第一个使控制器保持良好和精简,但在约会服务和客户服务之间创建了服务间依赖关系。第二个将更多逻辑放入控制器,但保持服务完全独立。

有人认为哪种做法更好?

谢谢~

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    纯粹从概念上考虑他的想法,我认为您的services 了解您的view models 没有任何意义。首先拥有控制器的主要原因之一是将视图逻辑与业务逻辑分开,但如果您的服务返回视图特定数据,那么它们本质上与您的业务逻辑相关。

    理想情况下,我希望该方法如下所示:

    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 等获取相关域层信息的逻辑。关于所有业务到域映射的去向,我一直在进行内部辩论,并坚持一个愚蠢的视图模型和事物控制器的想法,我一直将它们放在服务中......
    • 这正是 automapper 所针对的场景。很高兴我能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2010-10-14
    相关资源
    最近更新 更多