ファットコントローラーをリファクタリングしたことはありますか? 表現の多層モデルを作成する必要がありましたか? ビューにデータを追加し、コントローラーコードを書き換えますか? 何かおかしいと思っていましたか?
その理由は、多くのMVCフレームワークがMVCパターンに完全に準拠しておらず、それらに気付かずにそれを使用する人々がMVCパターンからさらに逸脱するためです。 それは非常に単純で、 ウィキペディアで説明されているように思えますが、何度も何度もそれを理解するのに問題があります。
この古典的なシックコントローラーアクションを見てください。
public ActionResult AddComment(int articleId, string content)
{
// -
var article = ArticleRepository.Instance.GetById(articleId);
if (article == null)
return View("ArticleNotFound");
var comment = new Comment
{
ArticleId = articleId,
Content = content
};
CommentRepository.Instance.Add(comment);
//
var viewModel = new ArticleViewModel
{
Article = article,
Comments = CommentRepository.Instance.GetByArticleId(articleId)
};
return View("Article", viewModel);
}
:
@Model ArticleViewModel
<header><h1>@Model.Article.Title</h1></header>
<article>@Model.Article.Content</article>
<ul>
@foreach (var comment in Model.Comments)
{
<li>@comment.Content</li>
}
</ul>
?
- , . , . Model MVC.
- , . : , . View.
ASP.NET MVC, MVC-. , .
MVC
Model — , ORM,
, . MVC . Model — , - . , , , . .
( ) , : API: , , . -, .
, ( , ) , , :
public interface IArticleService
{
//
// ,
// , .
void AddComment(string commentContent);
}
View — ,
- View , , . . , ( ). - , ( ).
, , , %PageName%ViewModel
( ).
MVC , , , ! ( , , .)
, . , . , , , Model.
, , . "Helper"-. , , View.
Controller — -
, ( -) . , , :
- ()
- ( ), ( )
- ,
( MVC , -, , , .)
, , %PageName%ViewModelProvider
, .
ASP.NET MVC
. , , . ASP.NET MVC? . Autofac Ninject, , .
:
- Autofac .
- , .
View
ASP.NET MVC , , . , WebViewPage
c Execute
— WebPageExecutingBase
, .
WebViewPage
, @inherits
:
( - , )
using System.Web.Mvc;
namespace ASP
{
// ArticleViewModel
// int-
public abstract class ArticlePageBase: WebViewPage<int>
{
// Autofac ,
// .
// ,
public IArticleRepository ArticleRepository { get; set; }
// ,
public ICommentRepository CommentRepository { get; set; }
// , ,
//
public IArticleRecomendationService RecomendationService { get; set; }
}
}
(Razor- )
@inherits ArticlePageBase
@{
//
var article = ArticleRepository.GetById(Model);
var comments = CommentRepository.GetByArticleId(Model);
var recommendedArticles = RecomendationService.GetRecomendations(Model);
}
@* *@
, , , . . Autofac , , .
, , , InitializePage
, , :
public abstract class ArticlePageBase: WebViewPage<int>
{
public IArticleRepository ArticleRepository { get; set; }
// ,
protected Article Article;
protected override void InitializePage()
{
Article = ArticleRepository.GetById(Model);
}
}
@inherits ArticlePageBase
<h1>@Article.Title</h1>
C#- ( , ):
@inherits ArticlePageBase
@{
//
var article = ArticleRepository.Get(Model);
var comments = CommentRepository.GetByArticleId(Model);
var recommendedArticles = RecomendationService.GetRecomendations(Model);
}
<h1>@ArticleService.Get(Model).Name</h1>
<header><h1>@article.Title</h1></header>
<article>@article.Content</article>
<ul>
@foreach (var comment in comments)
{
<li>@comment.Content</li>
}
</ul>
<ul>
@foreach (var recommendedArticle in recommendedArticles)
{
//
}
</ul>
, .
View ASP.NET MVC Core
Razor ASP.NET MVC Core @inject
. , , , :
@model int
@inject IArticleRepository ArticleRepository
@{
var article = ArticleRepository.GetById(Model)
}
<h1>@article.Title</h1>
, ConfigureServices
Startup
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//
services.AddTransient<IArticleRepository, ArticleRepository>();
//
}
, :
public ActionResult AddComment(int articleId, string content)
{
//
// . .
try
{
ArticleService.AddComment(articleId, content);
}
catch (ArticleNotFoundException e)
{
return View("ArticleNotFound");
}
return View("Article", articleId);
}
. . - , , — .
MVC — ADR
MVC - . - -. , , , , , . SRP. .
. — ADR ( PHP), . MVC:
- - - -. :
- , , , .
- , : , — . .
- Reflection- . . — "", .
- Responder , View : , , XML JSON .
ADR- .NET.
!
MVC
(SRP)
Autofac
Castle Windsor
Autofac
ASP.NET MVC Core
Paul M. Jones ADR
ADR
ADR