Skip to content

Commit

Permalink
fix MapsterMapper#295 add CodeGenerationConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
chaowlert committed Jan 24, 2021
1 parent b56ff38 commit d7a8397
Show file tree
Hide file tree
Showing 32 changed files with 615 additions and 293 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"mapster.tool": {
"version": "7.0.3",
"version": "7.1.3",
"commands": [
"dotnet-mapster"
]
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster.Core/Mapster.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<AssemblyOriginatorKeyFile>Mapster.Core.snk</AssemblyOriginatorKeyFile>
<PackageIcon>icon.png</PackageIcon>
<PackageIconUrl>https://cloud.githubusercontent.com/assets/5763993/26522718/d16f3e42-4330-11e7-9b78-f8c7402624e7.png</PackageIconUrl>
<Version>1.0.0</Version>
<Version>1.1.2</Version>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Mapster</RootNamespace>
Expand Down
3 changes: 2 additions & 1 deletion src/Mapster.Core/Mapster.Core.csproj.DotSettings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http:https://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http:https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=enums/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mapcontext/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mapcontext/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=register/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
134 changes: 134 additions & 0 deletions src/Mapster.Core/Register/AdaptAttributeBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Mapster
{
public class AdaptAttributeBuilder
{
public BaseAdaptAttribute Attribute { get; }
public Dictionary<Type, Dictionary<string, PropertySetting>> TypeSettings { get; } = new Dictionary<Type, Dictionary<string, PropertySetting>>();
public List<Func<Type, Type?>> AlterTypes { get; } = new List<Func<Type, Type?>>();

public AdaptAttributeBuilder(BaseAdaptAttribute attribute)
{
this.Attribute = attribute;
}

public AdaptAttributeBuilder ForTypes(params Type[] types)
{
foreach (var type in types)
{
if (!this.TypeSettings.ContainsKey(type))
this.TypeSettings.Add(type, new Dictionary<string, PropertySetting>());
}

return this;
}

public AdaptAttributeBuilder ForAllTypesInNamespace(Assembly assembly, string @namespace)
{
foreach (var type in assembly.GetTypes())
{
if (type.Namespace == @namespace && !this.TypeSettings.ContainsKey(type))
this.TypeSettings.Add(type, new Dictionary<string, PropertySetting>());
}

return this;
}

public AdaptAttributeBuilder ForType<T>(Action<PropertySettingBuilder<T>>? propertyConfig = null)
{
if (!this.TypeSettings.TryGetValue(typeof(T), out var settings))
{
settings = new Dictionary<string, PropertySetting>();
this.TypeSettings.Add(typeof(T), settings);
}

propertyConfig?.Invoke(new PropertySettingBuilder<T>(settings));
return this;
}

public AdaptAttributeBuilder ExcludeTypes(params Type[] types)
{
foreach (var type in types)
{
this.TypeSettings.Remove(type);
}

return this;
}

public AdaptAttributeBuilder ExcludeTypes(Func<Type, bool> predicate)
{
foreach (var type in this.TypeSettings.Keys.ToList())
{
if (predicate(type))
this.TypeSettings.Remove(type);
}

return this;
}

public AdaptAttributeBuilder IgnoreAttributes(params Type[] attributes)
{
this.Attribute.IgnoreAttributes = attributes;
return this;
}

public AdaptAttributeBuilder IgnoreNoAttributes(params Type[] attributes)
{
this.Attribute.IgnoreNoAttributes = attributes;
return this;
}

public AdaptAttributeBuilder IgnoreNamespaces(params string[] namespaces)
{
this.Attribute.IgnoreNamespaces = namespaces;
return this;
}

public AdaptAttributeBuilder IgnoreNullValues(bool value)
{
this.Attribute.IgnoreNullValues = value;
return this;
}

public AdaptAttributeBuilder MapToConstructor(bool value)
{
this.Attribute.MapToConstructor = value;
return this;
}

public AdaptAttributeBuilder MaxDepth(int depth)
{
this.Attribute.MaxDepth = depth;
return this;
}

public AdaptAttributeBuilder PreserveReference(bool value)
{
this.Attribute.PreserveReference = value;
return this;
}

public AdaptAttributeBuilder ShallowCopyForSameType(bool value)
{
this.Attribute.ShallowCopyForSameType = value;
return this;
}

public AdaptAttributeBuilder AlterType<TFrom, TTo>()
{
this.AlterTypes.Add(type => type == typeof(TFrom) ? typeof(TTo) : null);
return this;
}

public AdaptAttributeBuilder AlterType(Func<Type, bool> predicate, Type toType)
{
this.AlterTypes.Add(type => predicate(type) ? toType : null);
return this;
}
}
}
39 changes: 39 additions & 0 deletions src/Mapster.Core/Register/CodeGenerationConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Collections.Generic;

namespace Mapster
{
public class CodeGenerationConfig
{
public List<AdaptAttributeBuilder> AdaptAttributeBuilders { get; } = new List<AdaptAttributeBuilder>();
public List<GenerateMapperAttributeBuilder> GenerateMapperAttributeBuilders { get; } = new List<GenerateMapperAttributeBuilder>();
public AdaptAttributeBuilder Default { get; } = new AdaptAttributeBuilder(new AdaptFromAttribute("void"));

public AdaptAttributeBuilder AdaptTo(string name, MapType? mapType = null)
{
var builder = new AdaptAttributeBuilder(new AdaptToAttribute(name) {MapType = mapType ?? 0});
AdaptAttributeBuilders.Add(builder);
return builder;
}

public AdaptAttributeBuilder AdaptFrom(string name, MapType? mapType = null)
{
var builder = new AdaptAttributeBuilder(new AdaptFromAttribute(name) {MapType = mapType ?? 0});
AdaptAttributeBuilders.Add(builder);
return builder;
}

public AdaptAttributeBuilder AdaptTwoWays(string name, MapType? mapType = null)
{
var builder = new AdaptAttributeBuilder(new AdaptTwoWaysAttribute(name) {MapType = mapType ?? 0});
AdaptAttributeBuilders.Add(builder);
return builder;
}

public GenerateMapperAttributeBuilder GenerateMapper(string name)
{
var builder = new GenerateMapperAttributeBuilder(new GenerateMapperAttribute());
GenerateMapperAttributeBuilders.Add(builder);
return builder;
}
}
}
49 changes: 49 additions & 0 deletions src/Mapster.Core/Register/GenerateMapperAttributeBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Mapster
{
public class GenerateMapperAttributeBuilder
{
public GenerateMapperAttribute Attribute { get; }
public HashSet<Type> Types { get; } = new HashSet<Type>();

public GenerateMapperAttributeBuilder(GenerateMapperAttribute attribute)
{
this.Attribute = attribute;
}

public GenerateMapperAttributeBuilder ForTypes(params Type[] types)
{
this.Types.UnionWith(types);
return this;
}

public GenerateMapperAttributeBuilder ForAllTypesInNamespace(Assembly assembly, string @namespace)
{
this.Types.UnionWith(assembly.GetTypes().Where(it => it.Namespace == @namespace));
return this;
}

public GenerateMapperAttributeBuilder ForType<T>()
{
this.Types.Add(typeof(T));
return this;
}

public GenerateMapperAttributeBuilder ExcludeTypes(params Type[] types)
{
this.Types.ExceptWith(types);
return this;
}

public GenerateMapperAttributeBuilder ExcludeTypes(Predicate<Type> predicate)
{
this.Types.RemoveWhere(predicate);
return this;
}

}
}
7 changes: 7 additions & 0 deletions src/Mapster.Core/Register/ICodeGenerationRegister.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Mapster
{
public interface ICodeGenerationRegister
{
void Register(CodeGenerationConfig config);
}
}
13 changes: 13 additions & 0 deletions src/Mapster.Core/Register/PropertySetting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Linq.Expressions;

namespace Mapster
{
public class PropertySetting
{
public bool Ignore { get; set; }
public string? TargetPropertyName { get; set; }
public Type? TargetPropertyType { get; set; }
public LambdaExpression? MapFunc { get; set; }
}
}
57 changes: 57 additions & 0 deletions src/Mapster.Core/Register/PropertySettingBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Mapster.Utils;

namespace Mapster
{
public class PropertySettingBuilder<T>
{
public Dictionary<string, PropertySetting> Settings { get; }
public PropertySettingBuilder(Dictionary<string, PropertySetting> settings)
{
this.Settings = settings;
}

private PropertySetting ForProperty(string name)
{
if (!this.Settings.TryGetValue(name, out var setting))
{
setting = new PropertySetting();
this.Settings.Add(name, setting);
}
return setting;
}

public PropertySettingBuilder<T> Ignore<TReturn>(Expression<Func<T, TReturn>> member)
{
var setting = ForProperty(member.GetMemberName());
setting.Ignore = true;
return this;
}

public PropertySettingBuilder<T> Map<TReturn>(Expression<Func<T, TReturn>> member, string targetPropertyName)
{
var setting = ForProperty(member.GetMemberName());
setting.TargetPropertyName = targetPropertyName;
return this;
}

public PropertySettingBuilder<T> Map<TReturn>(Expression<Func<T, TReturn>> member, Type targetPropertyType, string? targetPropertyName = null)
{
var setting = ForProperty(member.GetMemberName());
setting.TargetPropertyType = targetPropertyType;
setting.TargetPropertyName = targetPropertyName;
return this;
}

public PropertySettingBuilder<T> Map<TReturn, TReturn2>(Expression<Func<T, TReturn>> member, Expression<Func<T, TReturn2>> mapFunc, string? targetPropertyName = null)
{
var setting = ForProperty(member.GetMemberName());
setting.MapFunc = mapFunc;
setting.TargetPropertyName = targetPropertyName;
return this;
}

}
}
18 changes: 17 additions & 1 deletion src/Mapster.Core/Utils/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq.Expressions;

namespace Mapster.Utils
{
Expand All @@ -9,7 +10,22 @@ public static Type GetTypeInfo(this Type type)
{
return type;
}

#endif

public static string GetMemberName(this LambdaExpression lambda)
{
string? prop = null;
var expr = lambda.Body;
if (expr.NodeType == ExpressionType.MemberAccess)
{
var memEx = (MemberExpression)expr;
prop = memEx.Member.Name;
expr = (Expression?)memEx.Expression;
}
if (prop == null || expr?.NodeType != ExpressionType.Parameter)
throw new ArgumentException("Allow only first level member access (eg. obj => obj.Name)", nameof(lambda));
return prop;
}

}
}
Loading

0 comments on commit d7a8397

Please sign in to comment.