2011-06-14 68 views
19

我知道MVC是关于把事情放在正确的地方和它应该是的逻辑。我的控制器操作正在被业务逻辑(与数据存储无关)充满,我觉得我应该开始将一些逻辑移到不同的地方。我应该在哪里把我的控制器的业务逻辑MVC3

是否有一个约定,我应该放置这个逻辑?例如,我有以下位于控制器文件中的控制器:

adminPowerController 

    public ActionResult Create(string test1) 
    // business logic 
    // business logic 
    // business logic 
    return View(); 
    } 
    public ActionResult Index(string test1) 
    // business logic 
    // business logic 
    // business logic 
    return View(); 
    } 
+0

检查此相关问题:http://stackoverflow.com/q/3131798/64096 – 2011-06-14 09:51:30

回答

26

将业务逻辑推荐放置到服务层。因此,您可以定义一个代表业务运营的界面:

public interface IMyService 
{ 
    DomainModel SomeOperation(string input); 
} 

然后执行此服务。最后,控制器将使用它:

public class MyController: Controller 
{ 
    private readonly IMyService _service; 
    public class MyController(IMyService service) 
    { 
     _service = service; 
    } 

    public ActionResult Create(string input) 
    { 
     var model = _service.SomeOperation(input); 
     var viewModel = Mapper.Map<DomainModel, ViewModel>(model); 
     return View(viewModel); 
    } 
} 

并配置您的DI框架以将正确的服务实施传递到控制器。

备注:在我提供的示例中,我使用了AutoMapper将域模型转换为传递给视图的视图模型。

+2

此代码具有和AutoMapper的依赖性,因此OP可能需要了解该参考 – stack72 2011-06-14 09:52:04

+1

@ stack72,好点。我已经更新了我的答案以提供参考。 – 2011-06-14 09:53:27

+0

感谢您的反馈。什么是您用于服务层的文件和目录命名约定?我可以假设你将这些文件保存在一个名为Interfaces的目录中吗? – Geraldo 2011-06-14 09:58:30

5

我倾向于在我的MVC项目做的是尽可能多的业务逻辑,以保持尽可能我的行动之外,这样我可以测试他们

在某些情况下,我创建了一个服务层,然后使用

public class QuizRunner : IQuizRunner 
{ 
    private readonly IServiceProxyclient _quizServiceProxy; 
    public QuizRunner(IServiceProxyclient quizServiceProxy) 
    { 
     _quizServiceProxy = quizServiceProxy; 
    } 

    public GameCategory GetPrizeGameCategory(int prizeId) 
    { 
     return _quizServiceProxy.GetGameCategoryForPrizeId(prizeId); 
    } 

} 

public interface IQuizRunner 
{ 
    GameCategory GetPrizeGameCategory(int prizeId); 
} 



private IQuizRunner_serviceClass; 

public AdminPowercontroller(IQuizRunner serviceClass) 
{ 
    _serviceClass = serviceClass; 
} 


public ActionResult Create(string test1) 
    var itemsFromLogic = _serviceClass.Method1(); 
    return View(); 
} 
public ActionResult Index(string test1) 
    var gameCategory = _serviceClass.GetPrizeGameCategory(test1); 
    var viewModel = Mapper.Map<GameCategory, GameCategoryViewModel>(gameCategory); 
    return View(viewModel); 
} 

这使我的行为单独从我的业务层和不依赖

希望测试这有助于

Paul

+0

感谢您的反馈。什么是您用于服务层的文件和目录命名约定?如果你不介意你能告诉我一个包含实现IServiceLayerClass的类的典型文件是什么样的。只是文件的外壳,可能是传入或传出的参数。非常感谢。 – Geraldo 2011-06-14 10:00:24

+0

我已经更新了我的答案,以显示一个示例服务图层类 - 此类与web服务交互但展示了概念验证 – stack72 2011-06-14 10:07:22

+0

@ stack72 - 控制器如何使用正确的服务类调用? – Geraldo 2011-06-14 10:16:26

1

业务逻辑应该存在于与MVC框架和其他东西分离的域模型中。

现实世界的例子...

应用(我的一个域的实体)控制器:

[HttpPost] 
public ActionResult Withdraw(int applicationId){ 
    //find it from repository or whatever 
    var app=FindApplication(applicationId); 
    //force it do do stuff 
    a.Withdraw(); 
    //send back some response 
    return RedirectToAction("Application",new{applicationId}); 
} 

应用实体本身:

public class Application{ 
public void Withdraw(){ 
    //check if current user is authorized to withdraw applications 
    Authorize<CanWithdrawApplications>(); 
    //check if application itself can be withdrawn 
    ThrowIf(!CanBeWithdrawn(),"Application can't be withdrawn."); 
    //apply state changes 
    IsWithdrawn=true; 
    //raise domain event 
    Raise(new Withdrawn(this)); 
} 
public bool CanBeWithdrawn(){ 
    return !IsWithdrawn && !Project.Contract.IsSigned; 
} 
} 

想了解更多,您可能想看看domain driven design是关于什么。

+0

@Amis - 那么你通常会将应用程序实体放入某种服务目录? FindApplication如何工作? – Geraldo 2011-06-14 11:24:02

+0

@Geraldo我的应用程序实体位于名为'Domain'(仅了解.Net框架)的单独程序集中,文件夹“Model”中。 FindApplication直接调用NHibernate。 – 2011-06-14 12:45:10

+0

但是如果在逻辑层中使用dao,我应该在模型中注入daoservice吗? – 2014-09-28 06:31:02

相关问题