1

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, IDictionary2 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)

RashmiMs
  • 129
  • 14

1 Answers1

0

Try this.

public JobDetailsDto()
 {
    Mapping();
 }
 public void Mapping()
 {
    CreateMap<JobModel, JobDetailsDto>()
        .ForMember(d => d.ShipBranch, opt => opt.MapFrom(s => s.PriceBranch))
        .ForMember(d => d.ProjectManager, opt => opt.MapFrom(s => s.BidderId));
 }

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

_mapperConfig = new MapperConfiguration(cfg => { cfg.AddProfile<MappingProfile>(); });