Skip to content

Commit 8817161

Browse files
authored
Reduce the need for custom expressions. (#144)
Reducing the need for custom expressions in literal member maps.
1 parent d7f1cec commit 8817161

10 files changed

+593
-327
lines changed

src/AutoMapper.Extensions.ExpressionMapping/AutoMapper.Extensions.ExpressionMapping.csproj

+15
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,19 @@
3636
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
3737
</ItemGroup>
3838

39+
<ItemGroup>
40+
<Compile Update="Properties\Resources.Designer.cs">
41+
<DesignTime>True</DesignTime>
42+
<AutoGen>True</AutoGen>
43+
<DependentUpon>Resources.resx</DependentUpon>
44+
</Compile>
45+
</ItemGroup>
46+
47+
<ItemGroup>
48+
<EmbeddedResource Update="Properties\Resources.resx">
49+
<Generator>ResXFileCodeGenerator</Generator>
50+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
51+
</EmbeddedResource>
52+
</ItemGroup>
53+
3954
</Project>

src/AutoMapper.Extensions.ExpressionMapping/FindMemberExpressionsVisitor.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public MemberExpression Result
3030
if (string.IsNullOrEmpty(result) || next.Contains(result))
3131
result = next;
3232
else throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
33-
Resource.includeExpressionTooComplex,
33+
Properties.Resources.includeExpressionTooComplex,
3434
string.Concat(_newParentExpression.Type.Name, period, result),
3535
string.Concat(_newParentExpression.Type.Name, period, next)));
3636

@@ -50,7 +50,7 @@ protected override Expression VisitMember(MemberExpression node)
5050
if (node.Expression.NodeType == ExpressionType.MemberAccess && node.Type.IsLiteralType())
5151
_memberExpressions.Add((MemberExpression)node.Expression);
5252
else if (node.Expression.NodeType == ExpressionType.Parameter && node.Type.IsLiteralType())
53-
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.mappedMemberIsChildOfTheParameterFormat, node.GetPropertyFullName(), node.Type.FullName, sType.FullName));
53+
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.mappedMemberIsChildOfTheParameterFormat, node.GetPropertyFullName(), node.Type.FullName, sType.FullName));
5454
else
5555
_memberExpressions.Add(node);
5656
}

src/AutoMapper.Extensions.ExpressionMapping/MapperExtensions.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ TDestDelegate MapBody(Dictionary<Type, Type> typeMappings, XpressionMapperVisito
109109
TDestDelegate GetLambda(Dictionary<Type, Type> typeMappings, XpressionMapperVisitor visitor, Expression mappedBody)
110110
{
111111
if (mappedBody == null)
112-
throw new InvalidOperationException(Resource.cantRemapExpression);
112+
throw new InvalidOperationException(Properties.Resources.cantRemapExpression);
113113

114114
return (TDestDelegate)Lambda
115115
(
@@ -255,7 +255,7 @@ public static List<ParameterExpression> GetDestinationParameterExpressions(this
255255
/// <returns></returns>
256256
public static Dictionary<Type, Type> AddTypeMapping<TSource, TDest>(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider)
257257
=> typeMappings == null
258-
? throw new ArgumentException(Resource.typeMappingsDictionaryIsNull)
258+
? throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull)
259259
: typeMappings.AddTypeMapping(configurationProvider, typeof(TSource), typeof(TDest));
260260

261261
private static bool HasUnderlyingType(this Type type)
@@ -284,7 +284,7 @@ private static void AddUnderlyingTypes(this Dictionary<Type, Type> typeMappings,
284284
public static Dictionary<Type, Type> AddTypeMapping(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type sourceType, Type destType)
285285
{
286286
if (typeMappings == null)
287-
throw new ArgumentException(Resource.typeMappingsDictionaryIsNull);
287+
throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull);
288288

289289
if (sourceType.GetTypeInfo().IsGenericType && sourceType.GetGenericTypeDefinition() == typeof(Expression<>))
290290
{
@@ -357,7 +357,7 @@ public static Type ReplaceType(this Dictionary<Type, Type> typeMappings, Type so
357357
private static Dictionary<Type, Type> AddTypeMappingsFromDelegates(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, Type sourceType, Type destType)
358358
{
359359
if (typeMappings == null)
360-
throw new ArgumentException(Resource.typeMappingsDictionaryIsNull);
360+
throw new ArgumentException(Properties.Resources.typeMappingsDictionaryIsNull);
361361

362362
typeMappings.DoAddTypeMappingsFromDelegates
363363
(
@@ -372,7 +372,7 @@ private static Dictionary<Type, Type> AddTypeMappingsFromDelegates(this Dictiona
372372
private static void DoAddTypeMappingsFromDelegates(this Dictionary<Type, Type> typeMappings, IConfigurationProvider configurationProvider, List<Type> sourceArguments, List<Type> destArguments)
373373
{
374374
if (sourceArguments.Count != destArguments.Count)
375-
throw new ArgumentException(Resource.invalidArgumentCount);
375+
throw new ArgumentException(Properties.Resources.invalidArgumentCount);
376376

377377
for (int i = 0; i < sourceArguments.Count; i++)
378378
{

src/AutoMapper.Extensions.ExpressionMapping/Resource.Designer.cs renamed to src/AutoMapper.Extensions.ExpressionMapping/Properties/Resources.Designer.cs

+15-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<root>
3+
<!--
4+
Microsoft ResX Schema
5+
6+
Version 1.3
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
11+
associated with the data types.
12+
13+
Example:
14+
15+
... ado.net/XML headers & schema ...
16+
<resheader name="resmimetype">text/microsoft-resx</resheader>
17+
<resheader name="version">1.3</resheader>
18+
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19+
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20+
<data name="Name1">this is my long string</data>
21+
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22+
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23+
[base64 mime encoded serialized .NET Framework object]
24+
</data>
25+
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26+
[base64 mime encoded string representing a byte array form of the .NET Framework object]
27+
</data>
28+
29+
There are any number of "resheader" rows that contain simple
30+
name/value pairs.
31+
32+
Each data row contains a name, and value. The row also contains a
33+
type or mimetype. Type corresponds to a .NET class that support
34+
text/value conversion through the TypeConverter architecture.
35+
Classes that don't support this are serialized and stored with the
36+
mimetype set.
37+
38+
The mimetype is used for serialized objects, and tells the
39+
ResXResourceReader how to depersist the object. This is currently not
40+
extensible. For a given mimetype the value must be set accordingly:
41+
42+
Note - application/x-microsoft.net.object.binary.base64 is the format
43+
that the ResXResourceWriter will generate, however the reader can
44+
read any of the formats listed below.
45+
46+
mimetype: application/x-microsoft.net.object.binary.base64
47+
value : The object must be serialized with
48+
: System.Serialization.Formatters.Binary.BinaryFormatter
49+
: and then encoded with base64 encoding.
50+
51+
mimetype: application/x-microsoft.net.object.soap.base64
52+
value : The object must be serialized with
53+
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
54+
: and then encoded with base64 encoding.
55+
56+
mimetype: application/x-microsoft.net.object.bytearray.base64
57+
value : The object must be serialized into a byte array
58+
: using a System.ComponentModel.TypeConverter
59+
: and then encoded with base64 encoding.
60+
-->
61+
62+
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
63+
<xsd:element name="root" msdata:IsDataSet="true">
64+
<xsd:complexType>
65+
<xsd:choice maxOccurs="unbounded">
66+
<xsd:element name="data">
67+
<xsd:complexType>
68+
<xsd:sequence>
69+
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
70+
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
71+
</xsd:sequence>
72+
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
73+
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
74+
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
75+
</xsd:complexType>
76+
</xsd:element>
77+
<xsd:element name="resheader">
78+
<xsd:complexType>
79+
<xsd:sequence>
80+
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
81+
</xsd:sequence>
82+
<xsd:attribute name="name" type="xsd:string" use="required" />
83+
</xsd:complexType>
84+
</xsd:element>
85+
</xsd:choice>
86+
</xsd:complexType>
87+
</xsd:element>
88+
</xsd:schema>
89+
<resheader name="resmimetype">
90+
<value>text/microsoft-resx</value>
91+
</resheader>
92+
<resheader name="version">
93+
<value>1.3</value>
94+
</resheader>
95+
<resheader name="reader">
96+
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
97+
</resheader>
98+
<resheader name="writer">
99+
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
100+
</resheader>
101+
<data name="cannotCreateBinaryExpressionFormat" xml:space="preserve">
102+
<value>Cannot create a binary expression for the following pair. Node: {0}, Type: {1} and Node: {2}, Type: {3}.</value>
103+
<comment>0=leftNode; 1=leftNodeType; 2=rightNode; 3=rightNodeType</comment>
104+
</data>
105+
<data name="cantRemapExpression" xml:space="preserve">
106+
<value>Can't rempa expression</value>
107+
</data>
108+
<data name="expressionMapValueTypeMustMatchFormat" xml:space="preserve">
109+
<value>The source and destination types must be the same for expression mapping between literal types. Source Type: {0}, Source Description: {1}, Destination Type: {2}, Destination Property: {3}.</value>
110+
<comment>0=Source Type; 1=SourceDescription; 2=Destination Type; 3=Destination Property.</comment>
111+
</data>
112+
<data name="includeExpressionTooComplex" xml:space="preserve">
113+
<value>The Include value-type expression uses multiple sibling navigation objects "{0}", "{1}" and is too complex to translate.</value>
114+
<comment>0=FirstNavigationProperty, 1=SecondNavigationProperty</comment>
115+
</data>
116+
<data name="invalidArgumentCount" xml:space="preserve">
117+
<value>Source and destination must have the same number of arguments.</value>
118+
</data>
119+
<data name="invalidExpErr" xml:space="preserve">
120+
<value>Invalid expression type for this operation.</value>
121+
</data>
122+
<data name="mapperInfoDictionaryIsNull" xml:space="preserve">
123+
<value>Mapper Info dictionary cannot be null.</value>
124+
</data>
125+
<data name="srcMemberCannotBeNullFormat" xml:space="preserve">
126+
<value>SourceMember cannot be null. Source Type: {0}, Destination Type: {1}, Property: {2}.</value>
127+
<comment>0=SorceType; 1=DestinationType; 2=Name of the source property</comment>
128+
</data>
129+
<data name="typeMappingsDictionaryIsNull" xml:space="preserve">
130+
<value>Type Mappings dictionary cannot be null.</value>
131+
</data>
132+
<data name="customResolversNotSupported" xml:space="preserve">
133+
<value>Custom resolvers are not supported for expression mapping.</value>
134+
</data>
135+
<data name="mustBeExpressions" xml:space="preserve">
136+
<value>Arguments must be expressions.</value>
137+
</data>
138+
<data name="mappedMemberIsChildOfTheParameterFormat" xml:space="preserve">
139+
<value>The mapped member {0} is of type {1} and a child of the parameter type {2}. No reference type (parent of) {0} is available to map as an include.</value>
140+
<comment>0=memberName, 1=memberType; 2=parameterType</comment>
141+
</data>
142+
<data name="makeParentTypesMatchForMembersOfLiteralsFormat" xml:space="preserve">
143+
<value>For members of literal types, use IMappingExpression.ForMember() to make the parent property types an exact match. Parent Source Type: {0}, Parent Destination Type: {1}, Full Member Name "{2}".</value>
144+
<comment>0=typeSource, 1=typeDestination; 2=sourceFullName</comment>
145+
</data>
146+
</root>

0 commit comments

Comments
 (0)