ASP.Net 核心中的 AutoMapper 问题
An issue with AutoMapper in ASP.Net Core
我有2个类要映射:
public class Note
{
public Guid UserId { get; set; }
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
}
public class NoteDetailsVm : IMapWith<Note>
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Note, NoteDetailsVm>();
}
}
这里是映射配置文件和映射界面:
public class AssemblyMappingProfile : Profile
{
public AssemblyMappingProfile(Assembly assembly) =>
ApplyMappingsFromAssembly(assembly);
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = (from t in assembly.GetExportedTypes()
where t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapWith<>))
select t).ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
public interface IMapWith<T>
{
void Mapping(Profile profile) =>
profile.CreateMap(typeof(T), GetType());
}
我使用这种方法来处理请求并获取视图模型:
public async Task<NoteDetailsVm> Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
{
var entity = await _dbContext.Notes.FirstOrDefaultAsync(note => note.Id == request.Id, cancellationToken);
if (entity == null || entity.UserId != request.UserId)
{
throw new NotFoundException(nameof(Note), request.Id);
}
return _mapper.Map<NoteDetailsVm>(entity);
}
所以当我 运行 测试时,尽管我有必要的映射,但我还是得到了这样的错误:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.
Mapping types:
Note -> NoteDetailsVm
Notes.Domain.Note -> Notes.Application.Notes.Queries.GetNoteDetails.NoteDetailsVm
at lambda_method259(Closure , Object , NoteDetailsVm , ResolutionContext )
at Notes.Application.Notes.Queries.GetNoteDetails.GetNoteDetailsQueryHandler.Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
为什么映射不起作用,我该如何解决?
您很可能不会在测试中处理初始化。在此处查看本指南:https://www.thecodebuzz.com/unit-test-mock-automapper-asp-net-core-imapper/
它的本质是这几行代码:
if (_mapper == null)
{
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new SourceMappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
_mapper = mapper;
}
他们确保有一个使用正确配置文件正确初始化的自动映射器实例。
好的,我已经设法解决了问题,它与上面的代码无关。刚刚将错误的程序集传递给配置文件构造函数
我有2个类要映射:
public class Note
{
public Guid UserId { get; set; }
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
}
public class NoteDetailsVm : IMapWith<Note>
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Note, NoteDetailsVm>();
}
}
这里是映射配置文件和映射界面:
public class AssemblyMappingProfile : Profile
{
public AssemblyMappingProfile(Assembly assembly) =>
ApplyMappingsFromAssembly(assembly);
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = (from t in assembly.GetExportedTypes()
where t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapWith<>))
select t).ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
public interface IMapWith<T>
{
void Mapping(Profile profile) =>
profile.CreateMap(typeof(T), GetType());
}
我使用这种方法来处理请求并获取视图模型:
public async Task<NoteDetailsVm> Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
{
var entity = await _dbContext.Notes.FirstOrDefaultAsync(note => note.Id == request.Id, cancellationToken);
if (entity == null || entity.UserId != request.UserId)
{
throw new NotFoundException(nameof(Note), request.Id);
}
return _mapper.Map<NoteDetailsVm>(entity);
}
所以当我 运行 测试时,尽管我有必要的映射,但我还是得到了这样的错误:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.
Mapping types:
Note -> NoteDetailsVm
Notes.Domain.Note -> Notes.Application.Notes.Queries.GetNoteDetails.NoteDetailsVm
at lambda_method259(Closure , Object , NoteDetailsVm , ResolutionContext )
at Notes.Application.Notes.Queries.GetNoteDetails.GetNoteDetailsQueryHandler.Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
为什么映射不起作用,我该如何解决?
您很可能不会在测试中处理初始化。在此处查看本指南:https://www.thecodebuzz.com/unit-test-mock-automapper-asp-net-core-imapper/
它的本质是这几行代码:
if (_mapper == null)
{
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new SourceMappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
_mapper = mapper;
}
他们确保有一个使用正确配置文件正确初始化的自动映射器实例。
好的,我已经设法解决了问题,它与上面的代码无关。刚刚将错误的程序集传递给配置文件构造函数