I am trying to map a class to a record and it seems to blow up everytime.
The class I have is
public class CreateStockRequestDto
{
public CreateStockRequestDto(string name, string locationId, int quantity)
{
Name = name;
LocationId = locationId;
Quantity = quantity;
}
public string Name { get; init; }
public int Quantity { get; set; }
public string? Sku { get; set; }
public string LocationId { get; init; }
}
I want it to map to a record
public record Stock
{
public Stock(StockId stockId, string itemName, int quantity, string? sku = null)
{
if (!Guid.TryParse(stockId.Id, out _))
{
throw new ArgumentException($"Invalid stock id {stockId.Id}", nameof(stockId));
}
if (quantity <= 0)
{
throw new ArgumentException($"Invalid quantity : {quantity}", nameof(quantity));
}
if (!IsValidItemName(itemName))
{
throw new ArgumentException($"Invalid item name {itemName}", nameof(itemName));
}
StockId = stockId;
ItemName = itemName;
Quantity = quantity;
Sku = sku;
}
public StockId StockId { get; init; }
public string ItemName { get; init; }
public int Quantity { get; init; }
public string? Sku { get; init; }
private static bool IsValidItemName(string itemName)
{
return Regex.IsMatch(itemName, RegularExpressions.ItemNameRegex);
}
}
I am using Automapper for mapping functionality, but I keep getting an error which states
Location.Domain.ValueObjects.Stock needs to have a constructor with 0 args or only optional args. Validate your configuration for details. (Parameter 'type')
public class StockProfile : Profile
{
public StockProfile()
{
CreateMap<Stock, CreateStockResponseDto>()
.ForMember(dest => dest.Id, input => input.MapFrom(src => src.StockId.Id))
.ForMember(dest => dest.Name, input => input.MapFrom(src => src.ItemName));
CreateMap<CreateStockRequestDto, Stock>()
.ForPath(x => x.StockId, opt => opt.MapFrom(o => new StockId(Guid.NewGuid().ToString())))
.ForMember(dest => dest.Quantity, opt => opt.MapFrom(o => o.Quantity))
.ForMember(dest => dest.ItemName, act => act.MapFrom(src => src.Name));
}
}
CodePudding user response:
For your scenario, you need Constructor mapping by providing the constructor parameters via .ForCtorParam()
.
public class StockProfile : Profile
{
public StockProfile()
{
...
CreateMap<CreateStockRequestDto, Stock>()
.ForCtorParam("quantity", opt => opt.MapFrom(src => src.Quantity))
.ForCtorParam("stockId", opt => opt.MapFrom(src => new StockId(Guid.NewGuid().ToString())))
.ForCtorParam("itemName", opt => opt.MapFrom(src => src.Name));
}
}