Skip to content

Commit

Permalink
Stay with the existing design of using configured data to model maps …
Browse files Browse the repository at this point in the history
…to retrieve the type mappings.
  • Loading branch information
BlaiseD committed Mar 10, 2020
1 parent 6600b12 commit d85adef
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Authors>Jimmy Bogard</Authors>
<LangVersion>latest</LangVersion>
<VersionPrefix>3.1.0-preview02</VersionPrefix>
<VersionPrefix>3.1.0-preview03</VersionPrefix>
<WarningsAsErrors>true</WarningsAsErrors>
<NoWarn>$(NoWarn);1701;1702;1591</NoWarn>
</PropertyGroup>
Expand Down
14 changes: 8 additions & 6 deletions src/AutoMapper.Extensions.ExpressionMapping/MapperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,20 +279,22 @@ public static Dictionary<Type, Type> AddTypeMapping(this Dictionary<Type, Type>
return typeMappings;
}

private static void AddIncludedTypeMaps(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type source, Type dest)
private static void AddIncludedTypeMaps(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type source/*model*/, Type dest/*data*/)//model to date
{
AddTypeMaps(configurationProvider.ResolveTypeMap(source, dest));
//Stay with the existing design of using configured data to model maps to retrieve the type mappings.
//This is needed for property map custom expressions.
AddTypeMaps(configurationProvider.ResolveTypeMap(sourceType: dest/*data*/, destinationType: source/*model*/));

void AddTypeMaps(TypeMap typeMap)
{
if (typeMap == null)
return;

foreach (var includedBase in typeMap.IncludedBaseTypes)
typeMappings.AddTypeMapping(configurationProvider, includedBase.SourceType, includedBase.DestinationType);
foreach (TypePair baseTypePair in typeMap.IncludedBaseTypes)
typeMappings.AddTypeMapping(configurationProvider, baseTypePair.DestinationType/*model*/, baseTypePair.SourceType/*data*/);

foreach (var includedDerived in typeMap.IncludedDerivedTypes)
typeMappings.AddTypeMapping(configurationProvider, includedDerived.SourceType, includedDerived.DestinationType);
foreach (TypePair derivedTypePair in typeMap.IncludedDerivedTypes)
typeMappings.AddTypeMapping(configurationProvider, derivedTypePair.DestinationType/*model*/, derivedTypePair.SourceType/*data*/);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,14 @@ public class ExpressionMappingPropertyFromDerviedType : AutoMapperSpecBase
private List<BaseEntity> _source;
private IQueryable<BaseEntity> entityQuery;

public class BaseDTO
{
public Guid Id { get; set; }
}

public class BaseEntity
{
public Guid Id { get; set; }
}

public class DTO : BaseDTO
{
public string Name { get; set; }
public string Description { get; set; }
}

public class Entity : BaseEntity
{
public string Name { get; set; }
}

protected override MapperConfiguration Configuration
{
get
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddExpressionMapping();
cfg.CreateMap<BaseEntity, BaseDTO>();
cfg.CreateMap<BaseDTO, BaseEntity>();
cfg.CreateMap<Entity, DTO>()
.ForMember(dest => dest.Description, opts => opts.MapFrom(src => string.Concat(src.Id.ToString(), " - ", src.Name)))
.IncludeBase<BaseEntity, BaseDTO>();
cfg.CreateMap<DTO, Entity>()
.IncludeBase<BaseDTO, BaseEntity>();
cfg.AddProfile(typeof(DerivedTypeProfile));
});
return config;
}
Expand Down Expand Up @@ -88,5 +59,38 @@ public void Should_support_propertypath_expressions_with_properties_from_sub_typ
// Assert
entityQuery.ToList().Count().ShouldBe(1);
}

public class DerivedTypeProfile : Profile
{
public DerivedTypeProfile()
{
CreateMap<BaseEntity, BaseDTO>();

CreateMap<Entity, DTO>()
.ForMember(dest => dest.Description, opts => opts.MapFrom(src => string.Concat(src.Id.ToString(), " - ", src.Name)))
.IncludeBase<BaseEntity, BaseDTO>();
}
}

public class BaseDTO
{
public Guid Id { get; set; }
}

public class BaseEntity
{
public Guid Id { get; set; }
}

public class DTO : BaseDTO
{
public string Name { get; set; }
public string Description { get; set; }
}

public class Entity : BaseEntity
{
public string Name { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public void Works_for_inherited_properties()
Expression<Func<DerivedModel, bool>> selection = s => s.Nested.NestedTitle2 == "nested test";

//Act
Expression<Func<DerivedDataModel, bool>> selectionMapped = mapper.Map<Expression<Func<DerivedDataModel, bool>>>(selection);
List<DerivedDataModel> items = DataObjects.Where(selectionMapped).ToList();
Expression<Func<DerivedData, bool>> selectionMapped = mapper.Map<Expression<Func<DerivedData, bool>>>(selection);
List<DerivedData> items = DataObjects.Where(selectionMapped).ToList();

//Assert
Assert.True(items.Count == 1);
Expand All @@ -36,8 +36,8 @@ public void Works_for_inherited_properties_on_base_types()
Expression<Func<RootModel, bool>> selection = s => ((DerivedModel)s).Nested.NestedTitle2 == "nested test";

//Act
Expression<Func<DataModel, bool>> selectionMapped = mapper.MapExpression<Expression<Func<DataModel, bool>>>(selection);
List<DataModel> items = DataObjects.Where(selectionMapped).ToList();
Expression<Func<RootData, bool>> selectionMapped = mapper.MapExpression<Expression<Func<RootData, bool>>>(selection);
List<RootData> items = DataObjects.Where(selectionMapped).ToList();

//Assert
Assert.True(items.Count == 1);
Expand Down Expand Up @@ -122,11 +122,11 @@ public void Throws_exception_when_mapped_string_is_a_child_of_the_parameter()

private void SetupQueryableCollection()
{
DataObjects = new DerivedDataModel[]
DataObjects = new DerivedData[]
{
new DerivedDataModel() { OtherID = 2, Title2 = "nested test", ID = 1, Title = "test", DescendantField = "descendant field" },
new DerivedDataModel() { OtherID = 3, Title2 = "nested", ID = 4, Title = "title", DescendantField = "some text" }
}.AsQueryable<DerivedDataModel>();
new DerivedData() { OtherID = 2, Title2 = "nested test", ID = 1, Title = "test", DescendantField = "descendant field" },
new DerivedData() { OtherID = 3, Title2 = "nested", ID = 4, Title = "title", DescendantField = "some text" }
}.AsQueryable<DerivedData>();

Orders = new OrderDto[]
{
Expand All @@ -146,7 +146,7 @@ private void SetupQueryableCollection()
}

private static IQueryable<OrderDto> Orders { get; set; }
private static IQueryable<DerivedDataModel> DataObjects { get; set; }
private static IQueryable<DerivedData> DataObjects { get; set; }

private void SetupAutoMapper()
{
Expand Down Expand Up @@ -181,7 +181,7 @@ public class DerivedModel : RootModel
public string DescendantField { get; set; }
}

public class DataModel
public class RootData
{
public int ID { get; set; }
public string Title { get; set; }
Expand All @@ -190,7 +190,7 @@ public class DataModel
public string Title2 { get; set; }
}

public class DerivedDataModel : DataModel
public class DerivedData : RootData
{
public string DescendantField { get; set; }
}
Expand Down Expand Up @@ -231,10 +231,10 @@ public class ForPathCustomerProfile : Profile
{
public ForPathCustomerProfile()
{
CreateMap<RootModel, DataModel>()
.Include<DerivedModel, DerivedDataModel>();
CreateMap<RootData, RootModel>()
.Include<DerivedData, DerivedModel>();

CreateMap<DerivedDataModel, DerivedModel>()
CreateMap<DerivedData, DerivedModel>()
.ForPath(d => d.Nested.NestedTitle, opt => opt.MapFrom(src => src.Title))
.ForPath(d => d.Nested.NestedTitle2, opt => opt.MapFrom(src => src.Title2))
.ReverseMap();
Expand Down

0 comments on commit d85adef

Please sign in to comment.