Skip to content

Commit

Permalink
Merge remote-tracking branch 'eswann/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
satano committed Sep 28, 2017
2 parents aa612fd + 3b66f1d commit 7cd3354
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 36 deletions.
8 changes: 4 additions & 4 deletions src/Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="AutoMapper, Version=6.0.2.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll</HintPath>
<Reference Include="AutoMapper, Version=6.1.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.6.1.0\lib\net45\AutoMapper.dll</HintPath>
</Reference>
<Reference Include="ExpressMapper, Version=1.9.1.0, Culture=neutral, PublicKeyToken=ac363faa09311ba0, processorArchitecture=MSIL">
<HintPath>..\packages\Expressmapper.1.9.1\lib\net45\ExpressMapper.dll</HintPath>
</Reference>
<Reference Include="Mapster, Version=3.0.2.0, Culture=neutral, PublicKeyToken=2f39883af23c29a8, processorArchitecture=MSIL">
<HintPath>..\packages\Mapster.3.0.2\lib\net45\Mapster.dll</HintPath>
<Reference Include="Mapster, Version=3.1.0.0, Culture=neutral, PublicKeyToken=2f39883af23c29a8, processorArchitecture=MSIL">
<HintPath>..\packages\Mapster.3.1.0\lib\net45\Mapster.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
4 changes: 2 additions & 2 deletions src/Benchmark/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="6.0.2" targetFramework="net451" />
<package id="AutoMapper" version="6.1.0" targetFramework="net451" />
<package id="Expressmapper" version="1.9.1" targetFramework="net451" />
<package id="Mapster" version="3.0.2" targetFramework="net451" />
<package id="Mapster" version="3.1.0" targetFramework="net451" />
</packages>
1 change: 1 addition & 0 deletions src/Mapster.Tests/Mapster.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<Compile Include="WhenMappingComplexClasses.cs" />
<Compile Include="WhenMappingDerived.cs" />
<Compile Include="WhenMappingArrays.cs" />
<Compile Include="WhenMappingIEnumerableClass.cs" />
<Compile Include="WhenMappingPrivateFieldsAndProperties.cs" />
<Compile Include="WhenMappingWithDictionary.cs" />
<Compile Include="WhenMappingRecordTypes.cs" />
Expand Down
35 changes: 29 additions & 6 deletions src/Mapster.Tests/WhenIncludeDerivedClasses.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mapster.Tests
{
Expand All @@ -25,6 +21,25 @@ public void Map_Including_Derived_Class()
((CarDto)dto).Make.ShouldBe("Toyota");
}

[TestMethod]
public void Map_Including_Derived_Class_With_List()
{
TypeAdapterConfig<Vehicle, VehicleDto>.NewConfig()
.Include<Car, CarDto>()
.Include<Bike, BikeDto>()
.Compile();

var vehicles = new List<Vehicle>
{
new Car {Id = 1, Name = "Car", Make = "Toyota", ChassiNumber = "XXX"},
new Bike {Id = 2, Name = "Bike", Brand = "BMX"},
};
var dto = vehicles.Adapt<List<Vehicle>, IList<VehicleDto>>();

((CarDto)dto[0]).Make.ShouldBe("Toyota");
((BikeDto)dto[1]).Brand.ShouldBe("BMX");
}

#region test classes
public abstract class Vehicle
{
Expand All @@ -36,6 +51,10 @@ public class Car : Vehicle
public string Make { get; set; }
public string ChassiNumber { get; set; }
}
public class Bike : Vehicle
{
public string Brand { get; set; }
}

public abstract class VehicleDto
{
Expand All @@ -47,6 +66,10 @@ public class CarDto : VehicleDto
public string Make { get; set; }
public string ChassiNumber { get; set; }
}
public class BikeDto : VehicleDto
{
public string Brand { get; set; }
}
#endregion
}
}
13 changes: 12 additions & 1 deletion src/Mapster.Tests/WhenMappingArrays.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,24 @@ public void List_To_Array_Is_Mapped()
[TestMethod]
public void List_To_Multi_Dimensional_Array_Is_Mapped()
{
var source = new List<int> {1, 2, 3, 4, 5};
var source = new List<int> { 1, 2, 3, 4, 5 };
var target = source.Adapt<int[,,]>();
target.GetLength(0).ShouldBe(1);
target.GetLength(1).ShouldBe(1);
target.GetLength(2).ShouldBe(5);
}

[TestMethod]
public void Multi_Dimensional_Array_To_List_Is_Mapped()
{
var source = new [,] {{1, 2}, {3, 4}};
var target = source.Adapt<List<int>>();
target[0].ShouldBe(1);
target[1].ShouldBe(2);
target[2].ShouldBe(3);
target[3].ShouldBe(4);
}

[TestMethod]
public void Can_Map_Multi_Dimensional_Array_Of_Poco()
{
Expand Down
21 changes: 21 additions & 0 deletions src/Mapster.Tests/WhenMappingConditionally.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;

Expand Down Expand Up @@ -38,6 +39,26 @@ public void Failed_Condition_Primitive_Does_Not_Map()
dto.Name.ShouldBeNull();
}

[TestMethod]
public void Map_Multiple_Condition()
{
TypeAdapterConfig<SimplePoco, SimpleDto>.NewConfig()
.Map(dest => dest.Name, src => "1", cond => cond.Name == "1")
.Map(dest => dest.Name, src => "2", cond => cond.Name == "2")
.Map(dest => dest.Name, src => "3", cond => cond.Name == "3")
.Map(dest => dest.Name, src => "4", cond => cond.Name == "4")
.Map(dest => dest.Name, src => "5", cond => cond.Name == "5")
.Map(dest => dest.Name, src => "0");

var list = Enumerable.Range(0, 6).Select(i => new SimplePoco {Name = i.ToString()}).ToList();
var dtos = list.Adapt<List<SimpleDto>>();

for (var i = 0; i < list.Count; i++)
{
dtos[i].Name.ShouldBe(i.ToString());
}
}

[TestMethod]
public void Passed_Condition_Primitive_Does_Map()
{
Expand Down
40 changes: 40 additions & 0 deletions src/Mapster.Tests/WhenMappingIEnumerableClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;
using System;
using System.Collections;

namespace Mapster.Tests
{
[TestClass]
public class WhenMappingIEnumerableClasses
{
public class ClassA
{
public int Id { get; set; }
}

public class ClassB : IEnumerable
{

public int Id { get; set; }

public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}

[TestMethod, Ignore]
public void Map_To_IEnumerable_Class_Should_Pass()
{
ClassA classA = new ClassA()
{
Id = 123
};

ClassB classB = classA.Adapt<ClassB>();
classB.Id.ShouldBe(classA.Id);
}

}
}
6 changes: 3 additions & 3 deletions src/Mapster.Tests/WhenMappingWithDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void Object_To_Dictionary_CamelCase()
Name = "test",
};

var dict = TypeAdapter.Adapt<Dictionary<string, object>>(poco);
var dict = TypeAdapter.Adapt<SimplePoco, Dictionary<string, object>>(poco);

dict.Count.ShouldBe(2);
dict["id"].ShouldBe(poco.Id);
Expand Down Expand Up @@ -150,7 +150,7 @@ public void Dictionary_To_Object_CamelCase()
["foo"] = "test",
};

var poco = TypeAdapter.Adapt<SimplePoco>(dict);
var poco = TypeAdapter.Adapt<Dictionary<string, object>, SimplePoco>(dict);
poco.Id.ShouldBe(dict["id"]);
poco.Name.ShouldBeNull();
}
Expand Down Expand Up @@ -207,7 +207,7 @@ public void Dictionary_Of_String_Mix()
["d"] = 4,
["e"] = null,
};
var result = dict.Adapt<Dictionary<string, int>>();
var result = dict.Adapt<Dictionary<string, int?>, Dictionary<string, int>>();
result.Count.ShouldBe(2);
result["A"].ShouldBe(1);
result["_b"].ShouldBe(2);
Expand Down
8 changes: 8 additions & 0 deletions src/Mapster/Adapters/BaseAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ protected Expression CreateBlockExpressionBody(Expression source, Expression des
//return result;
foreach (var tuple in arg.Settings.Includes)
{
//same type, no redirect to prevent endless loop
if (tuple.Source == arg.SourceType)
continue;

//type is not compatible, no redirect
if (!arg.SourceType.IsReferenceAssignableFrom(tuple.Source))
continue;

var blocks = new List<Expression>();
var vars = new List<ParameterExpression>();

Expand Down
3 changes: 1 addition & 2 deletions src/Mapster/Adapters/DictionaryAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,7 @@ protected override ClassModel GetClassModel(Type destinationType, CompileArgumen
private static Func<Expression, Expression, Expression> GetFunction(CompileArgument arg, Type dictType)
{
var strategy = arg.Settings.NameMatchingStrategy;
if (arg.MapType == MapType.MapToTarget &&
strategy.DestinationMemberNameConverter != NameMatchingStrategy.Identity)
if (strategy.DestinationMemberNameConverter != NameMatchingStrategy.Identity)
{
var args = dictType.GetGenericArguments();
var getMethod = typeof(CoreExtensions).GetMethods()
Expand Down
3 changes: 1 addition & 2 deletions src/Mapster/Mapster.NetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<Description>A fast, fun and stimulating object to object mapper. Kind of like AutoMapper, just simpler and way, way faster.</Description>
<Copyright>Copyright (c) 2016 Chaowlert Chaisrichalermpol, Eric Swann</Copyright>
<VersionPrefix>2.6.1</VersionPrefix>
<Authors>chaowlert;eric_swann</Authors>
<TargetFrameworks>net40;net45;netstandard1.3</TargetFrameworks>
<AssemblyName>Mapster</AssemblyName>
Expand All @@ -23,7 +22,7 @@
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>3.1.0</Version>
<Version>3.1.3</Version>
<RootNamespace>Mapster</RootNamespace>
</PropertyGroup>

Expand Down
33 changes: 25 additions & 8 deletions src/Mapster/Settings/ValueAccessingStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,41 @@ private static Expression CustomResolverFn(Expression source, IMemberModel desti
if (resolvers == null || resolvers.Count <= 0)
return null;

var invokes = new List<Tuple<Expression, Expression>>();

Expression getter = null;
LambdaExpression lastCondition = null;
foreach (var resolver in resolvers)
{
if (!destinationMember.Name.Equals(resolver.DestinationMemberName))
continue;
Expression invoke = resolver.Invoker == null
var invoke = resolver.Invoker == null
? Expression.PropertyOrField(source, resolver.SourceMemberName)
: resolver.Invoker.Apply(source);
getter = lastCondition != null
? Expression.Condition(lastCondition.Apply(source), getter, invoke)
: invoke;
lastCondition = resolver.Condition;

if (resolver.Condition == null)
{
getter = invoke;
break;
}

var condition = resolver.Condition.Apply(source);
invokes.Add(Tuple.Create(condition, invoke));
}
if (lastCondition != null)
getter = Expression.Condition(lastCondition.Apply(source), getter, Expression.Constant(getter.Type.GetDefault(), getter.Type));

if (invokes.Count > 0)
{
invokes.Reverse();
if (getter == null)
{
var type = invokes[0].Item2.Type;
getter = Expression.Constant(type.GetDefault(), type);
}
foreach (var invoke in invokes)
{
getter = Expression.Condition(invoke.Item1, invoke.Item2, getter);
}
}

return getter;
}

Expand Down
10 changes: 2 additions & 8 deletions src/Mapster/Utils/ExpressionEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,8 @@ public static Expression CreateCountExpression(Expression source, bool allowCoun
{
if (source.Type.GetArrayRank() == 1)
return Expression.ArrayLength(source); //array.Length
else
{
//array.GetLength(0) * array.GetLength(1) * ...
var method = typeof(Array).GetMethod("GetLength", new[] { typeof(int) });
return Enumerable.Range(0, source.Type.GetArrayRank())
.Select(i => (Expression)Expression.Call(source, method, Expression.Constant(i)))
.Aggregate(Expression.Multiply);
}
else
return Expression.Property(source, "Length");
}
else
{
Expand Down

0 comments on commit 7cd3354

Please sign in to comment.