在我的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");
}

我敢肯定,服务层不应该知道的视图模型什么,但我也并不认为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)。 和具有控制器知道来调用正确的变压器。

我+1你的问题,因为我很想看到一个干净的方式做到这一点也无需手动编写一串代码映射模型。

如果您的服务层,专门致力于支持你的MVC应用程序,你可以考虑使用通过并从服务层通过为您的ViewModels部件的对象没有其他客户。这将避免需要自动映射在接听电话,你会从控制器所需的实际对象被发送。

您也可以考虑的的具有服务返回域对象,这将意味着自动映射应与服务的方法,而不是控制器动作被调用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top