I am working on Web API and have mappings to convert from Domain models to Application models using AutoMapper(10.1.1)
I have registered AutoMapper in Application layer
public static IServiceCollection ConfigureAppServices(this IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
//services.AddMvc().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<StartUp>())
// services.AddControllersWithViews();
return services;
}
Used this class in Web API startup.cs
services.ConfigureAppServices();
I have this generic interface for Mapping called IMapFrom
public interface IMapFrom<T>
{
void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
Mapping is from 'JobModel' to 'JobDetailsDto'
public class JobDetailsDto: IMapFrom<JobModel>
{
public JobDetailsDto()
{
}
public string Id { get; set; }
public string Name { get; set; }
public string JobType { get; set; }
public string ShipBranch { get; set; }
public string ProjectManager { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<JobModel, JobDetailsDto>()
.ForMember(d => d.ShipBranch, opt => opt.MapFrom(s => s.PriceBranch))
.ForMember(d => d.ProjectManager, opt => opt.MapFrom(s => s.BidderId));
}
}
JobModel.cs
public class JobModel
{
public JobModel()
{
}
public int Id { get; set; }
public DateTime BidDate { get; set; }
public string JobType { get; set; }
public DateTime CreatedDate { get; set; }
public string City { get; set; }
public string State { get; set; }
public string BidderId { get; set; }
public string PriceBranch { get; set; }
public string Name { get; set; }
}
I am using MediaTr to handle API requests
public async Task<JobDetailsDto> Handle(GetJobDetailsQuery request, CancellationToken cancellationToken)
{
var vm = await _context.JobModels
.Where(e => e.Id == request.Id)
.ProjectTo<JobDetailsDto>(_mapper.ConfigurationProvider)
.SingleOrDefaultAsync(cancellationToken);
return vm;
}
When I perform 'GET' which fetches data in 'JobModel' object and converts to 'JobDetailsDto' throws below error
System.InvalidOperationException: Missing map from Domain.Entities.JobModel to Application.ApplicationBusiness.Job.Queries.JobDetailsDto. Create using CreateMap<JobModel, JobDetailsDto>. at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, IDictionary
2 typePairCount, LetPropertyMaps letPropertyMaps, TypeMap& typeMap) at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpression(ExpressionRequest request, IDictionary2 typePairCount, LetPropertyMaps letPropertyMaps) at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpression(ExpressionRequest request) at AutoMapper.Internal.LockingConcurrentDictionary2.<>c__DisplayClass2_1.<.ctor>b__1() at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue() at System.Lazy1.get_Value() at AutoMapper.Internal.LockingConcurrentDictionary2.GetOrAdd(TKey key) at AutoMapper.QueryableExtensions.ExpressionBuilder.GetMapExpression(Type sourceType, Type destinationType, Object parameters, MemberInfo[] membersToExpand) at AutoMapper.QueryableExtensions.ProjectionExpression.ToCore(Type destinationType, Object parameters, IEnumerable1 memberPathsToExpand) at AutoMapper.QueryableExtensions.ProjectionExpression.ToCore[TResult](Object parameters, IEnumerable1 memberPathsToExpand) at AutoMapper.QueryableExtensions.ProjectionExpression.To[TResult](Object parameters, Expression1[] membersToExpand) at AutoMapper.QueryableExtensions.Extensions.ProjectTo[TDestination](IQueryable source, IConfigurationProvider configuration, Object parameters, Expression1[] membersToExpand) at AutoMapper.QueryableExtensions.Extensions.ProjectTo[TDestination](IQueryable source, IConfigurationProvider configuration, Expression`1[] membersToExpand)
Try this.
Another solution is instead of writing mapping inside dto, you should create MappingProfile, where you will add your Mappings. Then in your service you should add it in constructor