【问题标题】:MVC - How should a service layer to communicate with the controllerMVC - 服务层应该如何与控制器通信
【发布时间】:2012-01-22 08:44:26
【问题描述】:

我一直在为我的控制器操作使用以下模式:

public ActionResult Create(CreateViewModel model) {
    if( !ModelState.IsValid ) {
        return View(model); 
    }

    var project = new Project {
        Name = model.Name,
        // ...
    };

    projectRepository.Add(project);

    return RedirectToAction("Index");
}

这适用于简单的场景,但我遇到过一些存储库不够用的情况。我创建了一个服务层/类,它将处理保存项目和任何额外的业务逻辑(不是带有流畅验证或数据注释的正常验证)。

public class ProjectService : IProjectService {

    void AddProject(Project project) {
        // do business logic
        // ...

        repository.Add(project);
    }
}

我的服务层如何轻松地与我的控制器通信?

这些是我想与控制器沟通的类型:

  • 业务逻辑/验证错误
  • 数据库故障(保存失败等)

如果不从服务层返回真/假或状态代码,我该如何做到这一点?

【问题讨论】:

    标签: c# asp.net-mvc service-layer


    【解决方案1】:

    如果您选择例外,请小心,这些都是昂贵的。它也为您的控制器代码提供了额外的嵌套,具体取决于可能引发的异常数量。您真的应该只为异常情况抛出异常,而不是应该由应用程序的正常流程处理的事情。

    我会选择 Wouter de Kort 建议的另一条路线,将服务的返回类型用于消息传递对象。您可以使用服务可能遇到的各种情况在简单枚举上键入返回消息对象。这些在控制器中看起来更好,因为您可以使用 switch/case 而不是 try/catch 来处理枚举。

    更新

    消息传递对象的外观:

    public interface IServiceAbc
    {
        ServiceResponse InvokeMyService([params]);
    }
    
    public enum ResponseScenario
    {
        Success,
        DatabaseFailed,
        BusinessRuleViolated,
        ValidationRuleViolated
    }
    
    public class ServiceResponse
    {
        public ResponseScenario Scenario { get; internal set; }
        public string Message { get; internal set; }
    }
    

    【讨论】:

      【解决方案2】:

      如果您想在发生错误时返回详细消息,您始终可以使用异常。也许用特定的细节定义你自己的,或者重用已经在 .NET Framework 中的那些。

      如果这不是一个选项,您总是可以返回一个包装类,该类可以包含更详细的错误信息并在控制器中处理。

      【讨论】:

        猜你喜欢
        • 2012-03-09
        • 1970-01-01
        • 2013-10-05
        • 2012-01-10
        • 2012-01-06
        • 2020-08-17
        • 2012-06-01
        • 1970-01-01
        • 2014-09-19
        相关资源
        最近更新 更多