简体   繁体   中英

AutoMapper converter 'parameterless constructor' error

I want to do unit test checking automapper is working fine. Created map

CreateMap<List<BaseProd.Product>, List<TL.StockQuantity>>()
            .ConvertUsing<ProductStockQuantityConverter>();

Converter code:

public class ProductStockQuantityConverter : ITypeConverter<List<BaseProd.Product>, List<TL.StockQuantity>>
{
    private readonly IMapper mapper;
    private readonly ProductService productService;        

    public ProductStockQuantityConverter(IMapper mapper, ProductService productService)
    {
        this.mapper = mapper;
        this.productService = productService;
    }

    public List<TL.StockQuantity> Convert(List<BaseProd.Product> source, List<TL.StockQuantity> destination, ResolutionContext context)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));

        destination = new List<TL.StockQuantity>();

        foreach (var item in source)
        {
            destination.Add(new TL.StockQuantity()
            {
                ProductOriginalId = item.ErplId,
                Quantity = productService.GetQuantity(item.Id, ignorePresale: true).Quantity
            });
        }

        return destination;
    }
}

My unit test looks like

[Fact]
    public void TestB2BStockQuantityEqual()
    {
        List<BaseProd.Product> prodList = new List<BaseProd.Product>();
        List<TL.StockQuantity> stockQuantityList = new List<TL.StockQuantity>();

        BaseProd.Product firstProductItem = new BaseProd.Product()
        {
            ErplId = ...
            Quantity = ...
        };

        BaseProd.Product secondProductItem = new BaseProd.Product()
        {
            ErplId = ...
            Quantity = ...
        };

        TL.StockQuantity firstStockQuantityItem = new TL.StockQuantity()
        {
            ProductOriginalId = ...
            Quantity = ...
        };

        TL.StockQuantity secondStockQuantityItem = new TL.StockQuantity()
        {
            ProductOriginalId = ...
            Quantity = ...
        };

        prodList.Add(firstProductItem);
        prodList.Add(secondProductItem);

        stockQuantityList.Add(firstStockQuantityItem);
        stockQuantityList.Add(secondStockQuantityItem);

        List<TL.StockQuantity> expected = mapper.Map<List<TL.StockQuantity>>(prodList);
        Assert.Equal(expected, stockQuantityList);
    }

And the Equals method

public partial class StockQuantity : IEquatable<StockQuantity>
{
    public bool Equals(StockQuantity other)
    {
        bool equals =
            int.Equals(this.ProductOriginalId, other.ProductOriginalId) &&
            decimal.Equals(this.Quantity, other.Quantity);

        return equals;
    }
}

Now the problem is error 'parameterless constructor'

I can't do parameterless constructor in converter, even if I do it (tried on another example where I took repo from db) I got an error that repo is null. I don't have idea how can I do it correctly

Edit

Second partial class code:

public partial class StockQuantity
{
    public int ProductOriginalId { get; set; }
    public decimal Quantity { get; set; }
}

I got this problem in every Converter, If I am creating map and use

.ForMember(...)

it's ok but with using converter it fails

Error details

在此处输入图片说明

Edit

My BaseAutomapperTest class code

public abstract class BaseAutomapperTest
{
    public virtual bool IsConfigurationValid()
    {
        try
        {
            Mapper.AssertConfigurationIsValid();
            return true;
        }
        catch
        {
            return false;
        }
    }
}

public abstract class BaseAutomapperTest<TProfile> : BaseAutomapperTest where TProfile : Profile, new()
{
    protected MapperConfiguration config;
    protected IMapper mapper;

    public override bool IsConfigurationValid()
    {
        try
        {
            config.AssertConfigurationIsValid();
            return true;
        }
        catch
        {
            return false;
        }
    }

    public BaseAutomapperTest()
    {
        config = new MapperConfiguration(c => c.AddProfile<TProfile>());
        mapper = new Mapper(config);

        //config.AssertConfigurationIsValid<TProfile>();

    }
}

And class with this test from up

public class AutoMapperTests : BaseAutomapperTest<AutoMapperProfile>
{
    public AutoMapperTests()
        : base()
    {

    }

...

    [Fact]
    public void TestB2BStockQuantityEqual()
    {
        List<BaseProd.Product> prodList = new List<BaseProd.Product>();
        List<TL.StockQuantity> stockQuantityList = new List<TL.StockQuantity>();

        BaseProd.Product firstProductItem = new BaseProd.Product()
        {
            ErplId = 1,
            Quantity = new[] { new ProductWarehouseQuantity() }
        };

        BaseProd.Product secondProductItem = new BaseProd.Product()
        {
            ErplId = 2,
            Quantity = new[] { new ProductWarehouseQuantity() }
        };

        TL.StockQuantity firstStockQuantityItem = new TL.StockQuantity()
        {
            ProductOriginalId = 1,
            Quantity = 1
        };

        TL.StockQuantity secondStockQuantityItem = new TL.StockQuantity()
        {
            ProductOriginalId = 2,
            Quantity = 1
        };

        prodList.Add(firstProductItem);
        prodList.Add(secondProductItem);

        stockQuantityList.Add(firstStockQuantityItem);
        stockQuantityList.Add(secondStockQuantityItem);

        List<TL.StockQuantity> expected = mapper.Map<List<TL.StockQuantity>>(prodList);
        Assert.Equal(expected, stockQuantityList);
    }

...

}

What i want to tell you is that if you are using Autofac then you can resolve a dependency directly in your ProductStockQuantityConveter

for example

public class ProductStockQuantityConverter
{
    private readonly ProductService productservice = Container.Resolve<ProductService>();
    private readonly IMapper mapper = Container.Resolve<IMapper>();

    public ProductStockQuantityConverter()
    {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM