2011-06-14 72 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

相關問題