MVC - サービス層への通信コントローラ
-
27-10-2019 - |
質問
で私のASP.net MVCのアプリ私は薄い私のコントローラを維持するために、サービスレイヤとリポジトリを使用しています。典型的な詳細については、このようなルックスを見る読み込みます:
public ActionResult Details(int id)
{
var project = _projectService.GetById(id);
return View(Mapper.Map<Project, ProjectDetails>(project));
}
サービス層ます:
public class ProjectService : IProjectService
{
public Project GetById(int id)
{
var project = _projectRepository.GetProject(id);
// do some stuff
return project;
}
}
public class ProjectRepository : IProjectRepository
{
public Project GetProject(int id)
{
return context.Projects.Find(id);
}
}
ビューモデルにサービス層からの移行はかなり簡単に物事を平らにすることができた、なぜならautomapperのはとても簡単です。私は良い解決策を考え出すのに苦労ところ私のサービス層に合格するビューモデルから、他の直接を移動することです。
アクションを作成し、どのようなこのための良い方法です?のような状況では、
[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
// TODO
return RedirectToAction("Index");
}
私はかなり確信してサービス層は、ビューモデルについて何も知らないということだけど、私はまた、フラットなモデルを取り、Aにそれを作るのが得意ではないので、AutoMapperは、いずれかのこのシナリオではうまく機能していることはないと思います複雑なオブジェクト。
のように私のコントローラの外観は、サービス層で何を通信する必要がありますか?私は、できるだけ軽量のコントローラのコードを維持したい。
解決
あなたは、双方向のマッピングを定義して、周りの他の道を行くことができます:
[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
Project project = Mapper.Map<CreateProjectViewModel, Project>(model);
// pass the project entity to your service layer
_projectService.Create(project);
return RedirectToAction("Index");
}
またはあなたが最初にあなたがサービスから更新したいという既存のエンティティを取得したい場合がありますエンティティを更新する場合
[HttpPost]
public ActionResult Update(CreateProjectViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
Project project = _projectService.GetById(model.Id);
Mapper.Map<CreateProjectViewModel, Project>(model, project);
// pass the project entity to your service layer
_projectService.Update(project);
return RedirectToAction("Index");
}
他のヒント
私はこれはこれまでに行って見てきた唯一の方法は、例えば、手動でモデル変換クラスの束を作成することです。
public interface ITransformer<out To, in From>
where To : class
{
To Transform(From instance);
}
public class SomeDataToSomeViewModelTransformer : ITransformer<SomeViewModel, SomeDataModel>
{
public SomeViewModel Transform(SomeDataModel instance)
{
return new SomeViewModel
{
InvitationId = instance.Id,
Email = instance.EmailAddress,
GroupId = instance.Group.Id
};
}
}
そして、他の方法(ViewModel -> DataModel
)を戻るには、別の変圧器の実装。
そして、コントローラが正しいトランスを呼び出すために知って持っています。
I +1、私は手動でモデルをマッピングするためのコードの束を記述することなく、あまりにもこれを行うには素敵なきれいな方法を見てみたいので、あなたの質問ます。
あなたのサービス層はもっぱら自分のMVCアプリケーションと、あなたのviewmodelsの一部として経由して、サービス層から渡されたオブジェクトを使用して検討することもできていない他のクライアントをサポートするために専用されている場合。これは、コントローラから必要な実際のオブジェクトに送信されると思いとしてインバウンドコールを自動マップする必要性をなくすでしょう。
また、検討することもでき、のないのサービスは、ドメインオブジェクトを返した、これは自動マッピングは、サービス・メソッドではなく、コントローラのアクションで呼び出されるべきであることを意味してます。