0

我想知道:映射器抽象有多复杂?

假设我有一个控制器的动作

ActionResult Find(QueryInputModel query)

模型看起来像这样

class QueryInputModel
{
    public string Text {get;set;}
    public IEnumerable<string> RegionCodes {get;set;}
}

除其他外,将输入模型转换为视图模型是操作的责任

class QueryViewModel
{
    public string Text {get;set;}
    public IEnumerable<Region> Regions {get;set;}
}

class Region
{
    public string Name {get;set;}
    public string Code {get;set;}
}

其中视图模型中的区域名称应使用输入模型中的代码从 db 中获取。现在它是通过QueryMapper.Map(src)看起来像这样的方法完成的

public QueryViewModel Map(QueryInputModel source)
{
    var regions = regionRepository.Get(source.RegionCodes);
    var result = new QueryViewModel {Text=source.Text, Regions=regions};
}

将这样的抽象称为Mapper是否正确?可以将直接映射和数据库查询混合在一个方法中吗?

4

2 回答 2

1

好吧,这是我的看法。根据您的说法,您有一个用例“从区域代码中查找区域详细信息”。这个用例有两个输入端口和一个输出端口:

  • 用户输入查询的方式是一个输入端口。
  • DB 中从区域代码到区域详细信息的映射是另一个输入端口。
  • 将结果返回给用户的方式是输出端口。

Map您在函数中实现的所有逻辑都是您的用例逻辑。该函数应该看起来像这样。

public void FindRegionDetailsFromRegionCodes(IUserQuery userQuery,
                                             IRegionMapper regionMapper,
                                             IUserDisplay userResult) {
    var regions = regionMapper.Get(userQuery.RegionCodes);
    userResult.ShowResult(regions);
}

和:

interface IUserQuery {
  IEnumerable<string> RegionCodes { get; }
}

interface IRegionMapper {
  IEnumerable<Region> Get(IEnumerable<string> regionCodes);
}

interface IUserDisplay {
  void ShowResult(IEnumerable<Region> regions);
}

这样,用例代码只关心动作执行的逻辑,而不关心每件事是如何完成的细节。您可以通过 TCP 网络端口公开您的服务(通过适当地实现IUserQueryIUserDisplay),或通过抛出一对 D20 并查找随机文件C:\和饲养仓鼠来计算细节(通过适当地实现IRegionMapper)。

现在,事实是您在控制器操作中公开了这个用例?好的。因此,您的控制器操作可以FindRegionDetailsFromRegionCodes通过传递它来调用:

  • 你的QueryInputModel,实施IUserQuery
  • 你的QueryViewModel,实施IUserDisplay
  • 你的RegionRepository(我想这是类的名称),实现IRegionMapper

从输入复制Text到视图不是您的用例关心的问题。它应该由你的行动来完成。(作为我论文的支持论点,如果您在某些时候需要复制另一个字段,这不应该更改用例代码)

希望这可以帮助。为了回答您的问题,真正的映射发生在 DB 中,这就是为什么我只调用“DB”端口IRegionMapper

于 2014-01-17T14:36:25.430 回答
-1

您在 ViewModel 和 DataModel 之间的映射是手动映射,尝试使用一些喜欢映射的第三方,如 Automapper 或 Valueinjecter,两者也可以通过 Nuget 安装到您的项目文件中。个人更喜欢Valueinjecter,因为它更容易编码和理解。

于 2013-07-03T16:54:21.117 回答