2013-04-29 56 views
0

所以我在我的服務的方法,我會從一個控制器調用:MVC存儲庫模式與服務 - 如何獲得DAL錯誤?

public void SendMessage(Message message) { 
     message.Property = "Random"; 
     try { 
      // try some insert logic 
     } 
     catch (Exception) { 
      // if it fails undo some stuff 
      // return the errors 
      throw; 
     } 

     // if there are no errors on the return the operation was a success 
     // but how do I get the Service generated data? 
    } 

編輯:

所以,問題是不是真正的讓我的代碼工作這是個問題我與存儲庫模式同時使用服務層作爲「之間走」通信的DAL演示之間

所以我有一個單獨的程序集叫做DataLibrary

DataLibrary有我的模型(Message),我的資料庫和服務(MessageService

在我的MVC網站,我通常會有一個控制器,具有CRUD功能。這將是這個樣子:

public ActionResult Create(Message message) { 
    if(ModelState.IsValid) { 
     db.insert(message); 
    } 
    Return View(message); 
} 

但是,通過使用存儲庫模式,與通信服務層我有這個:

public ActionResult Create(MessageCreateModel message) { 
    if(ModelState.IsValid) { 
     MessageService.SendMessage(message.ToDTO()); 
    } 
    Return View(message); 
} 

我怎麼知道該操作是成功還是不成功爲什麼?

如何在上述同時從服務的業務邏輯中檢索填充數據?

如何在儘可能接近MVC設計模式/關注可擴展性的前提下,如何實現上述兩者?

+0

爲了澄清,服務層,回購和DTO包裝在一個單獨的程序集內。 – Smithy 2013-04-29 15:08:24

回答

0

首先,如果只是將工作委派給您的存儲庫,您爲什麼要經過服務?如果您已經正確實施了您的存儲庫(即作爲完整的抽象),則無需使用該服務。只需從控制器直接調用存儲庫即可。您可以在我的blog中閱讀有關存儲庫模式的更多信息。

但這並沒有真正解決這個問題。

那麼你如何處理錯誤?當涉及到例外情況時:Simply do not catch it;)Exceptions are after all exceptions並且不是您通常可以處理以實現預期結果的東西。

正如我們正在談論的數據層,通常意味着一個穩定的數據庫引擎,預計讀/寫操作將會成功。因此,除了使用異常外,不需要任何其他錯誤處理。

在ASP中。NET MVC可以處理與屬性的交易和使用try/catch來填充模型狀態,如圖here

[HttpPost, Transactional] 
public virtual ActionResult Create(CreateModel model) 
{ 
    if (!ModelState.IsValid) 
     return View(model); 

    try 
    { 
     model.Category = model.Category ?? "Allmänt"; 

     var instruction = new Instruction(CurrentUser); 
     Mapper.Map(model, instruction); 
     _repository.Save(instruction); 

     return RedirectToAction("Details", new {id = instruction.Id}); 
    } 
    catch (Exception err) 
    { 
     // Adds an error to prevent commit. 
     ModelState.AddModelError("", err.Message); 
     Logger.Error("Failed to save instruction for app " + CurrentApplication, err); 
     return View(model); 
    } 
} 
+0

我讀過你的博客文章,我有類似的問題,那裏的第一張海報。我有業務邏輯,我覺得應該進入一個服務層,因爲我需要在一個地方(控制器除外)使用refs到各種模型/回購站。如果我插入一個用戶,我該如何返回'用戶已存在的錯誤'? – Smithy 2013-04-29 20:37:56

+1

拋出一個異常 – jgauffin 2013-05-03 07:48:35

+0

現在總體感覺,我很抱歉遲到的迴應。如果它的工作返回對象,否則我可以拋出並捕獲我自己的錯誤內部和驗證對此:) – Smithy 2013-05-17 22:43:36

0

你真的沒有提供足夠的關於你的架構的信息來構建回答這個問題。但是,如果您想從SendMessage方法中獲得一個值,則添加一個返回值而不是void是一個很好的開始。

+0

哈哈。好的迴應。我正在尋找一些理論,然後我可以去研究。我希望我的編輯能夠說明我在找什麼。 – Smithy 2013-04-29 19:54:33

0

我覺得你應該先決定你怎麼來設計你的架構。你是否以服務爲導向,如果是的話,你的服務方法必須返回給通知控制器。所以認爲你的服務層像一個國家的邊界​​,另一個國家的邊界​​是控制器。而且你必須讓這兩個國家交易。這可以通過包含返回數據和服務錯誤等的返回對象來完成。

如果您只想將您的業務邏輯放入服務層,那麼您可能不需要獨立層。只是一些鬆散的耦合就足夠了。所以你可以返回基本的clr對象或域對象或應用程序對象。在這樣一個非常簡單的例子:

//AService service method 
public AnEntity ServiceMethod(AFilterViewModel aFilter) 
{ 
    //do some validation 
    try 
    { 
      //some transactional operations 
    } 
    catch 
    { 
      //do some log and rollback it... 
      throw; 
    } 
    var anEntity = _aRepository.GetSomeEntity(x=> x.Something == aFilter.Something); 
    return anEntity; 
} 

//controller method 
public ActionResult GetSomething(AFilterViewModel aFilter) 
{ 
    try 
    { 
      var entity = _aService.ServiceMethod(aFilter); 
      AViewModel model = MapToView(entity); 
      return View(model); 
    } 
    catch 
    { 
      return RedirectToAction("Error"); 
    } 
} 

正如你看到的上面的控制器和服務層的方法,可以分享彼此的對象。他們有彼此的界限,他們加在一起。但是你的架構決定了它們的耦合程度。

您也可以單向做這些映射。就像服務於控制器或控制器只服務。如果你不想在服務層使用viewmodel,你應該總是在服務層做映射。否則,請在控制器中進行對象映射。也不要忘了把你的viewmodel放到另一個庫中,這非常重要。這些就像「價值對象」。