我想知道:映射器抽象有多复杂?
假设我有控制器的动作
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 是否正确?可以在单个方法中混合使用直接映射和db查询吗?
答案 0 :(得分:1)
嗯,这是我的看法。根据您的说法,您有一个用例“从区域代码中查找区域详细信息”。该用例有两个输入端口和一个输出端口:
您在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网络端口公开您的服务(通过适当地实施IUserQuery
和IUserDisplay
),或者通过抛出一对D20并在C:\
上查找随机文件和繁殖仓鼠来计算详细信息(通过适当实施IRegionMapper
)。
现在,事实是你在控制器动作中暴露了这个用例?好。因此,您的控制器操作可以通过传递它来调用FindRegionDetailsFromRegionCodes
:
QueryInputModel
,正在实施IUserQuery
QueryViewModel
,正在实施IUserDisplay
RegionRepository
(我认为这是该课程的名称),实施IRegionMapper
将Text
从输入复制到视图不是您的用例关注的问题。这应该通过你的行动来完成。 (作为我论文的支持论据,如果你在某个时候复制另一个字段,这不应该改变用例代码)
希望这会有所帮助。为了回答你的问题,真正的映射发生在DB中,这就是为什么我只调用“DB”端口IRegionMapper
。
答案 1 :(得分:-1)
您在ViewModel和DataModel之间的映射是手动映射,尝试使用一些帮助映射第三方,如Automapper或Valueinjecter,两者也可以由Nuget安装到您的项目文件中。个人更喜欢Valueinjecter,因为它更容易编码和理解。