2011-12-16 18 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); 
    } 
} 

私のサービス層はコントローラと簡単に通信できますか?

これら

私は、コントローラと通信したいものの種類があります:

  • ビジネスロジック/検証エラー
  • データベース障害

どのようにすることができます(などを保存することができませんでした)サービスレイヤからtrue/falseまたはステータスコードを返すだけで済みます。

答えて

1

エラーが発生したときに詳細なメッセージを返す場合は、常に例外を使用できます。特定の詳細で独自のものを定義したり、既に.NET Frameworkにあるものを再利用したりすることもできます。

これはオプションではない場合は、より詳細なエラー情報を含むことができ、コントローラでそれを処理できるラッパークラスを常に返すことができます。

2

例外を選択すると注意してください。これらは高価です。それはあなたのコントローラコードに余分なネスティングも与えます。例外の数は投げられるかもしれません。あなたは例外的な条件に対して例外をスローするだけで、アプリケーションの通常のフローによって処理されるべきものではありません。

私はWouter de Kortが提案した別のルートを使用します。メッセージングオブジェクトにサービスの戻り値の型を使用します。サービスが遭遇する可能性のあるさまざまなケースで簡単な列挙型でリターンメッセージオブジェクトをキーすることができます。 try/catchではなくswitch/caseで列挙型を扱うことができるので、これらはコントローラでよりよく見えます。

メッセージングオブジェクトがどのように見えるかもしれないものを更新

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; } 
} 
関連する問題