2011-12-16 48 views
1

我一直在使用下面的模式为我的控制器操作的控制器进行通信:MVC - 应该如何服务层与

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); 
    } 
} 

如何将我的业务层容易地与我的控制器进行通信?

这些都是类型的东西,我想传达给控制器:

  • 业务逻辑/验证错误
  • 数据库故障(未能挽救等)

如何我这样做不只是返回服务层的真/假或状态代码?

回答

1

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

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

2

如果选择异常,请小心,这些代价很高。它也会为您的控制器代码提供额外的嵌套,具体取决于可能抛出的异常数量。你应该只为异常情况抛出异常,而不是应用程序的正常流程处理的异常。

我会去与其他路由Wouter de Kort建议,使用消息对象的服务的返回类型。您可以使用简单的枚举键输入返回消息对象,并使用服务可能遇到的各种情况。这些在控制器中看起来更好,因为您可以使用开关/外壳而不是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; } 
}