11using System ;
22using System . Collections . Generic ;
3+ using System . Linq ;
34using System . Linq . Expressions ;
45using System . Reflection ;
56using Ploeh . AutoFixture ;
@@ -16,7 +17,7 @@ public abstract class TestDataBuilder<TObject, TBuilder>
1617 where TObject : class
1718 where TBuilder : TestDataBuilder < TObject , TBuilder > , new ( )
1819 {
19- private readonly Dictionary < string , object > _properties = new Dictionary < string , object > ( ) ;
20+ private readonly Dictionary < string , object > _properties = new Dictionary < string , object > ( StringComparer . InvariantCultureIgnoreCase ) ;
2021 private ProxyBuilder < TObject > _proxyBuilder ;
2122
2223 /// <summary>
@@ -215,5 +216,48 @@ protected virtual TChildBuilder GetChildBuilder<TChildObject, TChildBuilder>(Fun
215216 modifier ( childBuilder ) ;
216217 return childBuilder ;
217218 }
219+
220+ /// <summary>
221+ /// Builds the object using the constructor with the most arguments.
222+ /// </summary>
223+ /// <returns></returns>
224+ protected virtual TObject BuildByConstructor ( )
225+ {
226+ var longestConstructor = typeof ( TObject )
227+ . GetConstructors ( )
228+ . OrderByDescending ( x => x . GetParameters ( ) . Length )
229+ . FirstOrDefault ( ) ;
230+
231+ if ( longestConstructor == null ) throw new ObjectCreationException ( ) ;
232+
233+ var parameterValues = longestConstructor
234+ . GetParameters ( )
235+ . Select ( x => CallGetWithType ( x . Name , x . ParameterType ) ) ;
236+
237+ return ( TObject ) longestConstructor . Invoke ( parameterValues . ToArray ( ) ) ;
238+ }
239+
240+ private object CallGetWithType ( string propertyName , Type propertyType )
241+ {
242+ // Make a Func<TObj, TPropertyType>
243+ var expressionDelegateType = typeof ( Func < , > ) . MakeGenericType ( typeof ( TObject ) , propertyType ) ;
244+
245+ // Make an expression parameter of type TObj
246+ var tObjParameterType = Expression . Parameter ( typeof ( TObject ) ) ;
247+
248+ var valueStoredInBuilder = typeof ( TBuilder )
249+ . GetMethods ( )
250+ . First ( method => method . Name == "Get" && method . ContainsGenericParameters && method . GetGenericArguments ( ) . Length == 1 )
251+ . MakeGenericMethod ( propertyType )
252+ . Invoke ( this , new object [ ]
253+ {
254+ Expression . Lambda (
255+ expressionDelegateType ,
256+ Expression . Property ( tObjParameterType , propertyName ) ,
257+ tObjParameterType )
258+ } ) ;
259+
260+ return valueStoredInBuilder ;
261+ }
218262 }
219263}
0 commit comments