Skip to content

Fix Issue #783 - Add new Feature RequireExplicitMappingPrimitive to config #784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/Mapster.Tests/WhenExplicitMappingRequired.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class WhenExplicitMappingRequired
public void TestCleanup()
{
TypeAdapterConfig.GlobalSettings.RequireExplicitMapping = false;
TypeAdapterConfig.GlobalSettings.RequireExplicitMappingPrimitive = false;
TypeAdapterConfig.GlobalSettings.Clear();
}

Expand Down Expand Up @@ -140,8 +141,60 @@ public void UnmappedChildPocoShouldFailed()
setter.Compile(); // Should fail here
}

[TestMethod]
public void RequireExplicitMappingPrimitiveWork()
{
TypeAdapterConfig.GlobalSettings.RequireExplicitMappingPrimitive = true;

TypeAdapterConfig<Source783, Destination783>.NewConfig();

Should.Throw<CompileException>(() =>
{
TypeAdapterConfig.GlobalSettings.Compile(); // throw CompileException
});

byte byteSource = 10;

byteSource.Adapt<byte>(); // Should work when the type is mapped to itself

Should.Throw<CompileException>(() =>
{
byteSource.Adapt<int>(); // throw CompileException, Do not map to another primitive type without registering the configuration
});

Should.NotThrow(() =>
{
TypeAdapterConfig<byte, int>.NewConfig();

byteSource.Adapt<int>(); // Not throw CompileException when config is registering
});

Should.NotThrow(() =>
{
TypeAdapterConfig<Source783, Destination783>.NewConfig()
.Map(dest=> dest.MyProperty, src=> int.Parse(src.MyProperty));
// it work works because int.Parse return Type Int. Type is mapped to itself (int -> int) without config.

var sourceMapconfig = new Source783() { MyProperty = "128" };
var resultMapconfig = sourceMapconfig.Adapt<Destination783>();

resultMapconfig.MyProperty.ShouldBe(128);
});

}


#region TestClasses

public class Source783
{
public string MyProperty { get; set; } = "";
}

public class Destination783
{
public int MyProperty { get; set; }
}

public enum NameEnum
{
Expand Down
2 changes: 2 additions & 0 deletions src/Mapster/Adapters/PrimitiveAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ protected override bool CanMap(PreCompileArgument arg)

protected override Expression CreateExpressionBody(Expression source, Expression? destination, CompileArgument arg)
{
if (arg.SourceType != arg.DestinationType && arg.Context.Config.RequireExplicitMappingPrimitive && !arg.ExplicitMapping)
throw new InvalidOperationException("Implicit mapping is not allowed (check GlobalSettings.RequireExplicitMapping) and no configuration exists");

if (arg.Settings.MapToTargetPrimitive == true)
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mapster/TypeAdapterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ private static List<TypeAdapterRule> CreateRuleTemplate()

public bool RequireDestinationMemberSource { get; set; }
public bool RequireExplicitMapping { get; set; }
public bool RequireExplicitMappingPrimitive { get; set; }
public bool AllowImplicitDestinationInheritance { get; set; }
public bool AllowImplicitSourceInheritance { get; set; } = true;
public bool SelfContainedCodeGeneration { get; set; }
Expand Down Expand Up @@ -495,7 +496,7 @@ private LambdaExpression CreateMapInvokeExpression(Type sourceType, Type destina

internal Expression CreateMapInvokeExpressionBody(Type sourceType, Type destinationType, Expression p)
{
if (RequireExplicitMapping)
if (RequireExplicitMapping || RequireExplicitMappingPrimitive)
{
var key = new TypeTuple(sourceType, destinationType);
_mapDict[key] = Compiler(CreateMapExpression(key, MapType.Map));
Expand All @@ -518,7 +519,7 @@ internal Expression CreateMapInvokeExpressionBody(Type sourceType, Type destinat

internal Expression CreateMapToTargetInvokeExpressionBody(Type sourceType, Type destinationType, Expression p1, Expression p2)
{
if (RequireExplicitMapping)
if (RequireExplicitMapping || RequireExplicitMappingPrimitive)
{
var key = new TypeTuple(sourceType, destinationType);
_mapToTargetDict[key] = Compiler(CreateMapExpression(key, MapType.MapToTarget));
Expand Down
Loading