1- namespace AutoMapper . UnitTests
1+ namespace AutoMapper . UnitTests ;
2+ public class When_mapping_with_contextual_values
23{
3- namespace ContextItems
4+ public class Source
45 {
5- public class When_mapping_with_contextual_values
6+ public int Value { get ; set ; }
7+ }
8+
9+ public class Dest
10+ {
11+ public int Value { get ; set ; }
12+ }
13+
14+ public class ContextResolver : IMemberValueResolver < Source , Dest , int , int >
15+ {
16+ public int Resolve ( Source src , Dest d , int source , int dest , ResolutionContext context )
617 {
7- public class Source
8- {
9- public int Value { get ; set ; }
10- }
18+ return source + ( int ) context . Items [ "Item" ] ;
19+ }
20+ }
1121
12- public class Dest
13- {
14- public int Value { get ; set ; }
15- }
22+ [ Fact ]
23+ public void Should_use_value_passed_in ( )
24+ {
25+ var config = new MapperConfiguration ( cfg =>
26+ {
27+ cfg . CreateMap < Source , Dest > ( )
28+ . ForMember ( d => d . Value , opt => opt . MapFrom < ContextResolver , int > ( src => src . Value ) ) ;
29+ } ) ;
1630
17- public class ContextResolver : IMemberValueResolver < Source , Dest , int , int >
18- {
19- public int Resolve ( Source src , Dest d , int source , int dest , ResolutionContext context )
20- {
21- return source + ( int ) context . Items [ "Item" ] ;
22- }
23- }
31+ var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value = 5 } , opt => { opt . Items [ "Item" ] = 10 ; } ) ;
2432
25- [ Fact ]
26- public void Should_use_value_passed_in ( )
27- {
28- var config = new MapperConfiguration ( cfg =>
29- {
30- cfg . CreateMap < Source , Dest > ( )
31- . ForMember ( d => d . Value , opt => opt . MapFrom < ContextResolver , int > ( src => src . Value ) ) ;
32- } ) ;
33+ dest . Value . ShouldBe ( 15 ) ;
34+ }
35+ }
3336
34- var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value = 5 } , opt => { opt . Items [ "Item" ] = 10 ; } ) ;
37+ public class When_mapping_with_contextual_values_wrong_overload : AutoMapperSpecBase
38+ {
39+ public class Source
40+ {
41+ public int Value { get ; set ; }
42+ }
3543
36- dest . Value . ShouldBe ( 15 ) ;
37- }
38- }
44+ public class Dest
45+ {
46+ public int Value { get ; set ; }
47+ }
3948
40- public class When_mapping_with_contextual_values_wrong_overload : AutoMapperSpecBase
41- {
42- public class Source
43- {
44- public int Value { get ; set ; }
45- }
49+ protected override MapperConfiguration CreateConfiguration ( ) => new ( cfg =>
50+ {
51+ cfg . CreateMap < Source , Dest > ( )
52+ . ForMember ( d => d . Value , opt => opt . MapFrom ( ( src , d , member , ctxt ) => { ctxt . Items [ "Item" ] = 2 ; return - 1 ; } ) ) ;
53+ } ) ;
4654
47- public class Dest
48- {
49- public int Value { get ; set ; }
50- }
55+ [ Fact ]
56+ public void Should_report_error ( )
57+ {
58+ new Action ( ( ) => Mapper . Map < Source , Dest > ( new Source { Value = 5 } ) ) . ShouldThrowException < AutoMapperMappingException > ( ex =>
59+ {
60+ var inner = ex . InnerException ;
61+ inner . ShouldBeOfType < InvalidOperationException > ( ) ;
62+ inner . Message . ShouldBe ( "Context.Items are only available when using a Map overload that takes Action<IMappingOperationOptions>!" ) ;
63+ } ) ;
64+ }
65+ }
5166
52- protected override MapperConfiguration CreateConfiguration ( ) => new ( cfg =>
53- {
54- cfg . CreateMap < Source , Dest > ( )
55- . ForMember ( d => d . Value , opt => opt . MapFrom ( ( src , d , member , ctxt ) => { ctxt . Items [ "Item" ] = 2 ; return - 1 ; } ) ) ;
56- } ) ;
67+ public class When_mapping_with_contextual_values_shortcut
68+ {
69+ public class Source
70+ {
71+ public int Value { get ; set ; }
72+ }
5773
58- [ Fact ]
59- public void Should_report_error ( )
60- {
61- new Action ( ( ) => Mapper . Map < Source , Dest > ( new Source { Value = 5 } ) ) . ShouldThrowException < AutoMapperMappingException > ( ex =>
62- {
63- var inner = ex . InnerException ;
64- inner . ShouldBeOfType < InvalidOperationException > ( ) ;
65- inner . Message . ShouldBe ( "Context.Items are only available when using a Map overload that takes Action<IMappingOperationOptions>!" ) ;
66- } ) ;
67- }
68- }
74+ public class Dest
75+ {
76+ public int Value { get ; set ; }
77+ }
6978
70- public class When_mapping_with_contextual_values_shortcut
79+ [ Fact ]
80+ public void Should_use_value_passed_in ( )
81+ {
82+ var config = new MapperConfiguration ( cfg =>
7183 {
72- public class Source
73- {
74- public int Value { get ; set ; }
75- }
84+ cfg . CreateMap < Source , Dest > ( )
85+ . ForMember ( d => d . Value , opt => opt . MapFrom ( ( src , d , member , ctxt ) => ( int ) ctxt . Items [ "Item" ] + 5 ) ) ;
86+ } ) ;
7687
77- public class Dest
78- {
79- public int Value { get ; set ; }
80- }
88+ var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value = 5 } , opt => opt . Items [ "Item" ] = 10 ) ;
8189
82- [ Fact ]
83- public void Should_use_value_passed_in ( )
84- {
85- var config = new MapperConfiguration ( cfg =>
86- {
87- cfg . CreateMap < Source , Dest > ( )
88- . ForMember ( d => d . Value , opt => opt . MapFrom ( ( src , d , member , ctxt ) => ( int ) ctxt . Items [ "Item" ] + 5 ) ) ;
89- } ) ;
90+ dest . Value . ShouldBe ( 15 ) ;
91+ }
92+ }
9093
91- var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value = 5 } , opt => opt . Items [ "Item" ] = 10 ) ;
94+ public class When_mapping_with_contextual_values_in_resolve_func
95+ {
96+ public class Source
97+ {
98+ public int Value1 { get ; set ; }
99+ }
92100
93- dest . Value . ShouldBe ( 15 ) ;
94- }
95- }
101+ public class Dest
102+ {
103+ public int Value1 { get ; set ; }
104+ }
96105
97- public class When_mapping_with_contextual_values_in_resolve_func
106+ [ Fact ]
107+ public void Should_use_value_passed_in ( )
108+ {
109+ var config = new MapperConfiguration ( cfg =>
98110 {
99- public class Source
100- {
101- public int Value1 { get ; set ; }
102- }
111+ cfg . CreateMap < Source , Dest > ( )
112+ . ForMember ( d => d . Value1 , opt => opt . MapFrom ( ( source , d , dMember , context ) => ( int ) context . Items [ "Item" ] + source . Value1 ) ) ;
113+ } ) ;
103114
104- public class Dest
105- {
106- public int Value1 { get ; set ; }
107- }
108-
109- [ Fact ]
110- public void Should_use_value_passed_in ( )
111- {
112- var config = new MapperConfiguration ( cfg =>
113- {
114- cfg . CreateMap < Source , Dest > ( )
115- . ForMember ( d => d . Value1 , opt => opt . MapFrom ( ( source , d , dMember , context ) => ( int ) context . Items [ "Item" ] + source . Value1 ) ) ;
116- } ) ;
115+ var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value1 = 5 } , opt => { opt . Items [ "Item" ] = 10 ; } ) ;
117116
118- var dest = config . CreateMapper ( ) . Map < Source , Dest > ( new Source { Value1 = 5 } , opt => { opt . Items [ "Item" ] = 10 ; } ) ;
117+ dest . Value1 . ShouldBe ( 15 ) ;
118+ }
119+ }
119120
120- dest . Value1 . ShouldBe ( 15 ) ;
121- }
122- }
121+ public class When_mapping_nested_context_items : AutoMapperSpecBase
122+ {
123+ public class Door { }
123124
124- public class When_mapping_nested_context_items : AutoMapperSpecBase
125- {
126- public class Door { }
125+ public class FromGarage
126+ {
127+ public List < FromCar > FromCars { get ; set ; }
128+ }
127129
128- public class FromGarage
129- {
130- public List < FromCar > FromCars { get ; set ; }
131- }
130+ public class ToGarage
131+ {
132+ public List < ToCar > ToCars { get ; set ; }
133+ }
132134
133- public class ToGarage
134- {
135- public List < ToCar > ToCars { get ; set ; }
136- }
135+ public class FromCar
136+ {
137+ public int Id { get ; set ; }
138+ public string Name { get ; set ; }
139+ public Door Door { get ; set ; }
140+ }
137141
138- public class FromCar
139- {
140- public int Id { get ; set ; }
141- public string Name { get ; set ; }
142- public Door Door { get ; set ; }
143- }
142+ public class ToCar
143+ {
144+ public int Id { get ; set ; }
145+ public string Name { get ; set ; }
146+ public Door Door { get ; set ; }
147+ }
144148
145- public class ToCar
149+ protected override MapperConfiguration CreateConfiguration ( ) => new ( cfg =>
150+ {
151+ cfg . CreateMap < FromGarage , ToGarage > ( )
152+ . ForMember ( dest => dest . ToCars , opts => opts . MapFrom ( ( src , dest , destVal , ctx ) =>
146153 {
147- public int Id { get ; set ; }
148- public string Name { get ; set ; }
149- public Door Door { get ; set ; }
150- }
154+ var toCars = new List < ToCar > ( ) ;
151155
152- protected override MapperConfiguration CreateConfiguration ( ) => new ( cfg =>
153- {
154- cfg . CreateMap < FromGarage , ToGarage > ( )
155- . ForMember ( dest => dest . ToCars , opts => opts . MapFrom ( ( src , dest , destVal , ctx ) =>
156- {
157- var toCars = new List < ToCar > ( ) ;
156+ ToCar toCar ;
157+ foreach ( var fromCar in src . FromCars )
158+ {
159+ toCar = ctx . Mapper . Map < ToCar > ( fromCar ) ;
160+ if ( toCar == null )
161+ continue ;
158162
159- ToCar toCar ;
160- foreach ( var fromCar in src . FromCars )
161- {
162- toCar = ctx . Mapper . Map < ToCar > ( fromCar ) ;
163- if ( toCar == null )
164- continue ;
163+ toCars . Add ( toCar ) ;
164+ }
165165
166- toCars . Add ( toCar ) ;
167- }
166+ return toCars ;
167+ } ) ) ;
168168
169- return toCars ;
170- } ) ) ;
169+ cfg . CreateMap < FromCar , ToCar > ( )
170+ . ConvertUsing ( ( src , dest , ctx ) =>
171+ {
172+ ToCar toCar = null ;
173+ FromCar fromCar = src ;
171174
172- cfg . CreateMap < FromCar , ToCar > ( )
173- . ConvertUsing ( ( src , dest , ctx ) =>
175+ if ( fromCar . Name != null )
176+ {
177+ toCar = new ToCar
174178 {
175- ToCar toCar = null ;
176- FromCar fromCar = src ;
177-
178- if ( fromCar . Name != null )
179- {
180- toCar = new ToCar
181- {
182- Id = fromCar . Id ,
183- Name = fromCar . Name ,
184- Door = ( Door ) ctx . Items [ "Door" ]
185- } ;
186- }
187-
188- return toCar ;
189- } ) ;
179+ Id = fromCar . Id ,
180+ Name = fromCar . Name ,
181+ Door = ( Door ) ctx . Items [ "Door" ]
182+ } ;
183+ }
184+
185+ return toCar ;
190186 } ) ;
187+ } ) ;
191188
192- [ Fact ]
193- public void Should_flow_context_items_to_nested_mappings ( )
189+ [ Fact ]
190+ public void Should_flow_context_items_to_nested_mappings ( )
191+ {
192+ var door = new Door ( ) ;
193+ var fromGarage = new FromGarage
194+ {
195+ FromCars = new List < FromCar >
194196 {
195- var door = new Door ( ) ;
196- var fromGarage = new FromGarage
197- {
198- FromCars = new List < FromCar >
199- {
200- new FromCar { Door = door , Id = 2 , Name = "Volvo" } ,
201- new FromCar { Door = door , Id = 3 , Name = "Hyundai" } ,
202- }
203- } ;
197+ new FromCar { Door = door , Id = 2 , Name = "Volvo" } ,
198+ new FromCar { Door = door , Id = 3 , Name = "Hyundai" } ,
199+ }
200+ } ;
204201
205- var toGarage = Mapper . Map < ToGarage > ( fromGarage , opts =>
206- {
207- opts . Items . Add ( "Door" , door ) ;
208- } ) ;
202+ var toGarage = Mapper . Map < ToGarage > ( fromGarage , opts =>
203+ {
204+ opts . Items . Add ( "Door" , door ) ;
205+ } ) ;
209206
210- foreach ( var d in toGarage . ToCars . Select ( c => c . Door ) )
211- {
212- d . ShouldBeSameAs ( door ) ;
213- }
214- }
207+ foreach ( var d in toGarage . ToCars . Select ( c => c . Door ) )
208+ {
209+ d . ShouldBeSameAs ( door ) ;
215210 }
216211 }
217212}
0 commit comments