我一直在阅读有关使用 NHibernate 和 AutoMapper 将 DTO 的 entityID 转换为域的实体的 StackOverflow 帖子。那里肯定有很多信息,但每个人似乎都有不同的建议,其中许多建议完全使用不同的工具(ValueInjecter)。此外,我发现的很多信息都是几年前的。因此,我再次提出这个问题,希望能为我解决问题。
我有以下 DTO 类:
public class PlaylistDto
{
public Guid Id { get; set;
public Guid StreamId { get; set; }
public List<PlaylistItemDto> Items { get; set; }
}
和相应的域:
public class Playlist
{
public Guid Id { get; set;
public Stream Stream { get; set; }
// Use interfaces so NHibernate can inject with its own collection implementation.
public IList<PlaylistItem> Items { get; set; }
}
首先,我声明我打算将这两个实体相互映射:
Mapper.CreateMap<Playlist, PlaylistDto>().ReverseMap();
Mapper.CreateMap<PlaylistItem, PlaylistItemDto>().ReverseMap();
Mapper.CreateMap<Stream, StreamDto>().ReverseMap();
ReverseMap 允许我轻松地声明双向映射。
此时,我可以毫不费力地将 Playlist 成功转换为 PlaylistDto:
// Singular:
PlaylistDto playlistDto = Mapper.Map<Playlist, PlaylistDto>(playlist);
// Collection:
List<PlaylistDto> playlistDtos = Mapper.Map<List<Playlist>, List<PlaylistDto>>(playlists);
这很好用。不需要额外的代码。但是,当我尝试绘制另一个方向时,就会出现问题。
playlistDto 仅存储对其 Stream 的 ID 引用。如果我将 DTO 转换为域,如下所示:
Playlist playlist = Mapper.Map<PlaylistDto, Playlist>(playlistDto);
那么无论 playlistDto 的 StreamID 是什么,播放列表的 Stream 始终为 null。
我想添加一个中间步骤,允许使用 Dto 的 entityId 通过 NHibernate 获取域的实体。
我没有使用 AutoMapper,我将通过以下方式实现:
playlist.Stream = StreamDao.Get(playlistDto.StreamId);
话虽如此,我有问题:
- 使用 AutoMapper 达成共识的最简单方法是什么?
- ValueInjecter 真的是我应该在这里考虑的选择吗?我是否会走上强迫 AutoMapper 做会导致头痛的事情的道路?
- 如果 ValueInjecter 是首选......它仍然被维护吗?该项目看起来非常过时。另外,我看到有人提到 ValueInjecter 不支持集合。如果是这样的话,这将是一个巨大的转变。
我见过的一些可能解决我的问题的例子:
Mapper.CreateMap<Person, Domain.Person>()
.ForMember(dest => dest.Address, opt => opt.ResolveUsing( src => { return new Address() {Address1 = src.Address, City = src.City, State = src.State }; }))
public class Id2EntityConverter<TEntity> : ITypeConverter<int, TEntity> where TEntity : EntityBase
{
public Id2EntityConverter()
{
Repository = ObjectFactory.GetInstance<Repository<TEntity>>();
}
private IRepository<TEntity> Repository { get; set; }
public TEntity ConvertToEntity(int id)
{
var toReturn = Repository.Get(id);
return toReturn;
}
#region Implementation of ITypeConverter<int,TEntity>
public TEntity Convert(ResolutionContext context)
{
return ConvertToEntity((int)context.SourceValue);
}
#endregion
}
(there's more to this, but this is the gist of it)
建议表示赞赏。谢谢!