Проблема с Mapster C# .net
Проблема в том,что когда #define PProductEnabled не закоменторована,в тесте получаются ошибки.Нужно как-то пофиксить. Буду рад любой помощи.
#define PChildCollectionIsReadOnly
//#define PChildCollectionIsTypedImpl
//#define PProductIsMutable
#define PProductEnabled
using System;
using System.Collections.Generic;
using Mapster;
namespace TheTechZap.SharedDemos.Main.MapsterTrial1.Tests.Main.AppCode.Pocos
{
public class ZDataMemberAttribute : Attribute
{
}
public class OrderMutableDto
{
readonly Lazy<IList<OrderItemMutableDto>> _orderItems;
public OrderMutableDto() => _orderItems = new Lazy<IList<OrderItemMutableDto>>(new List<OrderItemMutableDto>(100));
public DateTime BookedOn { get; set; }
[ZDataMemberAttribute]
public long CustomerId { get; set; }
[ZDataMemberAttribute]
public string? Notes { get; set; }
[UseDestinationValue]
[ZDataMemberAttribute]
public IList<OrderItemMutableDto> OrderItems => _orderItems.Value;
}
public interface IOrderMutableLocalNoBase
{
DateTime BookedOn { get; set; }
long CustomerId { get; set; }
string? Notes { get; set; }
[ZDataMemberAttribute]
[UseDestinationValue]
#if (PChildCollectionIsReadOnly && PChildCollectionIsTypedImpl)
IList<OrderItemMutable> OrderItems { get; }
#elif (PChildCollectionIsReadOnly && !PChildCollectionIsTypedImpl)
IList<IOrderItemMutable> OrderItems { get; }
#else
IList<IOrderItemMutable> OrderItems { get; set; }
#endif
}
public class OrderMutableLocalNoBase : IOrderMutableLocalNoBase
{
public DateTime BookedOn { get; set; }
[ZDataMemberAttribute]
public long CustomerId { get; set; }
public long Id { get; set; }
[ZDataMemberAttribute]
public string? Notes { get; set; }
[UseDestinationValue]
[ZDataMemberAttribute]
#if (PChildCollectionIsReadOnly && PChildCollectionIsTypedImpl)
public IList<OrderItemMutable> OrderItems { get; } = new List<OrderItemMutable>();
#elif (PChildCollectionIsReadOnly && !PChildCollectionIsTypedImpl)
public IList<IOrderItemMutable> OrderItems { get; } = new List<IOrderItemMutable>();
#else
public IList<IOrderItemMutable> OrderItems { get; set; } = new List<IOrderItemMutable>();
#endif
#if (PProductEnabled)
public IProduct? Product { get; set; }
#endif
}
public interface IHasProduct
{
IProduct? Product { get; }
}
public interface IOrderItemMutable //: IHasProduct
{
[ZDataMemberAttribute]
long Id { get; set; }
int Quantity { get; set; }
long? ProductId { get; set; }
long? OrderId { get; set; }
[ZDataMemberAttribute]
string? Notes { get; set; }
#if (PProductEnabled)
[AdaptIgnore]
IProduct? Product
{
get;
#if PProductIsMutable
set;
#endif
}
#endif
}
public class OrderItemMutable : IOrderItemMutable
{
[ZDataMemberAttribute]
public long Id { get; set; }
[ZDataMemberAttribute]
public string? Notes { get; set; }
public long? OrderId { get; set; }
public long? ProductId { get; set; }
public int Quantity { get; set; }
#if (PProductEnabled)
[AdaptIgnore]
public IProduct? Product { get; set; }
#endif
}
public class IProduct
{
public long Id { get; set; }
public long Notes { get; set; }
}
public class Product
{
public long Id { get; set; }
public long Notes { get; set; }
}
public class OrderItemMutableDto
{
[ZDataMemberAttribute]
public long Id { get; set; }
[ZDataMemberAttribute]
public string? Notes { get; set; }
public long? OrderId { get; set; }
public long? ProductId { get; set; }
public int Quantity { get; set; }
}
}
Тест
using System;
using System.Linq;
using FluentAssertions;
using LINQPad;
using Mapster;
using TheTechZap.SharedDemos.Main.MapsterTrial1.Tests.Main.AppCode.Pocos;
using Xunit;
namespace TheTechZap.SharedDemos.Main.MapsterTrial1.Tests.Main
{
public class MainTest
{
/// <summary>
/// Mapping from concrete to interface problems with child collections, solutions:
/// 1. Must provide ConstructUsing(), so Mapster knows which type to create.
/// 2. Child collections, readonly set. Mapster will fail on mapping whole class. Add `[UseDestinationValue]' attribute
/// to concrete class.
/// 3. use the explicit Adapt method, that DOES NOT accept type params, `Mapster.TypeAdapter.Adapt(dto, entity,
/// dto.GetType(), entity.GetType());`. Mapster used the Type params, an interface, to define destination type, problems
/// Indicates whether or not the specified type is a list.
/// Problems:
/// </summary>
public void BuildMapsterConfig(bool strict = true)
{
//Do explicit mapping, for debugging
if (strict)
TypeAdapterConfig.GlobalSettings.RequireExplicitMapping = true;
//TypeAdapterConfig<OrderMutableDto, OrderMutableDto>.NewConfig().TwoWays();
//TypeAdapterConfig<IOrderMutableLocalNoBase, OrderMutableDto>.NewConfig().TwoWays();
//TypeAdapterConfig<OrderMutableDto, OrderMutableLocalNoBase>.NewConfig().TwoWays();
TypeAdapterConfig<OrderMutableDto, OrderMutableLocalNoBase>.NewConfig().ConstructUsing(src => new OrderMutableLocalNoBase());
TypeAdapterConfig<OrderMutableDto, IOrderMutableLocalNoBase>.NewConfig().ConstructUsing(src => new OrderMutableLocalNoBase());
TypeAdapterConfig<OrderItemMutableDto, IOrderItemMutable>.NewConfig().ConstructUsing(src => new OrderItemMutable());
//TypeAdapterConfig<IOrderItemMutable, OrderItemMutable>.NewConfig().ConstructUsing(src => new OrderItemMutable());
//TypeAdapterConfig<IOrderMutableLocalNoBase, OrderMutableDto>.NewConfig().ConstructUsing(src => new OrderMutableDto());
TypeAdapterConfig.GlobalSettings.Default.IncludeMember((member, side) => member.GetCustomAttributes(true).OfType<ZDataMemberAttribute>().Any());
TypeAdapterConfig.GlobalSettings.Default.IgnoreMember((member, side) => !member.GetCustomAttributes(true).OfType<ZDataMemberAttribute>().Any());
if (strict) TypeAdapterConfig.GlobalSettings.Compile();
}
/*
in the poco class file compile constants will cause test to fail:
#define PChildCollectionIsReadOnly
//#define PChildCollectionIsTypedImpl
//#define PProductIsMutable
#define PProductEnabled
for success:
#define PChildCollectionIsReadOnly
//#define PChildCollectionIsTypedImpl
//#define PProductIsMutable
//#define PProductEnabled
Fix why this causes error: OrderItem and IOrderItem contain:
IProduct Product {get;set;}
We do not need to map Product, it should be ignored
*/
[Theory]
[InlineData(true, true, "target is var of type interface")]
[InlineData(false, true, "target is var of type interface")]
[InlineData(true, false, "target is var of type impl")]
[InlineData(false, false, "target is var of type impl")]
public void Test_domain_dto_to_entity_using_raw_mapster_debug_with_local_entity_class_attempt_to_fix(bool mappingStrict, bool targetIsInterface, string name)
{
BuildMapsterConfig(mappingStrict);
//IOrderMutableLocal entity = new OrderMutableLocal(new FluentValidationBusinessRuleManager<IOrderMutableLocal>(null));
IOrderMutableLocalNoBase entityCommon;
IOrderMutableLocalNoBase entityAsInterface = null;
OrderMutableLocalNoBase entityAsImpl = null;
if (targetIsInterface) entityAsInterface = new OrderMutableLocalNoBase();
else entityAsImpl = new OrderMutableLocalNoBase();
entityCommon = targetIsInterface ? entityAsInterface : entityAsImpl;
OrderMutableDto dto = new() { CustomerId = 987, Notes = "some notes here...", BookedOn = new DateTime(2001, 02, 03, 4, 5, 6) };
OrderMutableDto dto2 = new();
dto.OrderItems.Add(new OrderItemMutableDto { Id = 1, Notes = "1", Quantity = 1 });
dto.OrderItems.Add(new OrderItemMutableDto { Id = 2, Notes = "2", Quantity = 2 });
entityCommon.Dump("entity - before");
dto.Dump("dto - before");
entityCommon.Should().NotBeNull();
dto.Should().NotBeNull();
if (targetIsInterface) dto.Adapt(entityAsInterface, dto.GetType(), entityAsInterface.GetType());
else dto.Adapt(entityAsImpl);
//dto.Adapt(dto2);
entityCommon.Dump("entity - after");
dto.Dump("dto - after");
entityCommon.CustomerId.Should().Be(dto.CustomerId);
entityCommon.Notes.Should().Be(dto.Notes);
entityCommon.OrderItems.Should().HaveCount(2);
entityCommon.OrderItems.Should().AllBeOfType<OrderItemMutable>().And.AllBeAssignableTo<IOrderItemMutable>();
entityCommon.OrderItems.Select(i => i.Id).Should().Equal(1, 2);
entityCommon.OrderItems.Select(i => i.Notes).Should().Equal("1", "2");
}
[Fact]
public void Test_ping() { }
}
}