映射发生时自动调用自定义函数(用于填充属性)

时间:2012-01-15 10:50:39

标签: asp.net-mvc

我有一个编辑特定项目的视图。以下是我为此视图准备视图模型的操作:

  1. 检索项目信息
  2. 准备一个新的视图模型对象anp将我的项目映射到其中。
  3. 通过调用函数来填充它来准备TechnologyString。
  4. 显示视图。

    public ActionResult Edit(string slug)
    {
        // 1
        Project project = m_ProjectBusiness.GetProject(slug);
    
        // 2
        ProjectEditViewModel viewModel = new ProjectEditViewModel
        {
            ProjectToEdit = Mapper.Map<Project, ProjectFullViewModel>(project)                 
        };
    
        // 3
        viewModel.ProjectToEdit.TechnologyString = m_ProjectBusiness.ListTechnologies(project);
    
        // 4
        return View(viewModel);
    }
    
  5. 正如您在第3点所看到的,我在我的视图模型中填写了一个字符串(TechnologyString),位于我的对象ProjectToEdit下。我想知道在映射发生时是否可以直接(并自动)执行此操作?

    感谢。


    修改

    我找到了一个基于映射的解决方案。这是:

            Mapper.CreateMap<Project, ProjectFullViewModel>()
                 .ForMember(dest => dest.TechnologyString,
                            opt => opt.MapFrom(src => String.Join(" ", src.Technologies.Select(x => x.Name))));
    

    因此,我检索附加到项目的所有技术,并创建一个字符串,其中所有项目都用空格分隔。

    读者:请注意,下面的Darin解决方案适用于技术不属于我的域模型的情况。但在这种情况下它是。

1 个答案:

答案 0 :(得分:0)

这不是应该在映射级别处理的内容。您可以使用服务层,在该服务层中,您将为项目和技术定义聚合根:

public class ProjectAggregateRoot
{
    public Project Project { get; set; }
    public string TechnologyString { get; set; }
}

然后在服务层中有一个方法将返回此聚合根:

public ProjectAggregateRoot GetProjectBySlug(string slug)
{
    var project = _repo.GetProject(slug);
    var technoString = _repo.ListTechnologies(project);
    return new ProjectAggregateRoot
    {
        Project = project,
        TechnologyString = technoString
    }
}

然后您可以直接在服务层返回的聚合根和视图模型之间进行映射,如下所示:

public ActionResult Edit(string slug)
{
    var model = _service.GetProjectBySlug(slug);

    // now you have everything in the aggregate root to build your view model
    var viewModel = Mapper.Map<ProjectAggregateRoot, ProjectEditViewModel>(model);
    return View(viewModel);
}