2

肥大化したコントローラーを間引くために、MVCプロジェクトにサービスレイヤーを実装し始めています(リポジトリ/ユニットオブワークパターンもあります)。

私の質問は、子オブジェクトなどがたくさんあるページの複雑なビューモデルがあり、舞台裏でかなり多くのロジックが実行されているかどうかです(元の開発者が作成したコントローラーには、約4000行のコードが含まれていました。 !)複数のサービスを停止させても大丈夫ですか?または、すべてを実行する1つの大きなReportServiceが必要ですか?

私のコントローラーはこのように見え始めていますか?続行すると、ビューモデルを構築するために非常に多くの異なるサービスが呼び出される可能性があります。

これは問題ないように見えますか、それとも間違った方向に進み始めていますか?

public ViewResult Index(int? reportId)
    {
        // get the base report object
        var reportService = new ReportService();
        var report = reportService.GetByReportId(reportId);
        var model = Mapper.Map<Report, ReportViewModel>(report);

        // get the current active user
        var userService = new UserService();
        var user = userService.GetCurrentUser();
        model.User = Mapper.Map<User, ReportViewModel.UserViewModel>(user);

        // get the first unread message
        var messageService = new MessageService();
        var message = messageService.GetFirstUnread(user.Id);
        model.Message = Mapper.Map<Message, ReportViewModel.MessageViewModel>(message);

        // get the category navigation
        var categoryService = new CategoryService();
        var categoryNavigation = categoryService.GetCategoryNavigation(report.Id);
        model.CategoryNavigation = Mapper.Map<IEnumerable<Category>, IEnumerable<ReportViewModel.CategoryNavigationViewModel>>(categoryNavigation);

        return View(model);
    }
4

2 に答える 2

4

コントローラーに複数の小さなサービスがあっても問題ありません。ただし、ここで間違っていることが 1 つあります。

疎結合を実現するために、サービスはコントローラー全体を通じて利用可能であり、コンストラクターを通じて注入される必要があります。

だから、このようなもの:

private readonly IReportService _reportService;
private readonly IUserService _userService;

public SomeConstructor(IReportService reportService, IUserService userService, etc.) 
{
    _reportService = reportService;
    _userService = userService;
    // etc
}
于 2012-06-05T22:55:17.453 に答える
1

これは良いアプローチのように見えますが、代わりのアプローチは、子アクションを使用してこれらの一部を分割することです。ただし、最適なソリューションは、特定のユース ケースによって異なります。

たとえば、ViewModel プロパティCategoryNavigationがビューで使用され、いくつかの異なるビューで役立つ可能性がある一種のナビゲーション 'ウィジェット' を作成する場合、これを ChildAction などに分割する方がよい場合があります。

[ChildActionOnly]
public ActionResult CategoryNavigationWidget(int reportId)
{
    // get the category navigation
    var categoryService = new CategoryService();
    var categoryNavigation = categoryService.GetCategoryNavigation(report.Id);

    return PartialView(categoryNavigation);
}

次に、どのビューでも、次のようにしてその ChildAction をレンダリングできます。

   @{ Html.RenderAction("CategoryNavigationWidget", "Report", 
           new { reportId = Model.ReportId }); }

これが良いアイデアかどうかは、おそらく「ウィジェット」が再利用可能かどうかに依存します。

于 2012-06-06T03:48:38.357 に答える