3636using System . Linq ;
3737using System . Dynamic ;
3838using System . Reflection ;
39- using Fasterflect ;
4039
4140namespace SmartStore . ComponentModel
4241{
@@ -59,7 +58,7 @@ namespace SmartStore.ComponentModel
5958 /// Dictionary: Any of the extended properties are accessible via IDictionary interface
6059 /// </summary>
6160 [ Serializable ]
62- public class Expando : DynamicObject , IDynamicMetaObjectProvider
61+ public class Expando : DynamicObject
6362 {
6463 /// <summary>
6564 /// Instance of object passed in
@@ -71,7 +70,7 @@ public class Expando : DynamicObject, IDynamicMetaObjectProvider
7170 /// </summary>
7271 private Type _instanceType ;
7372
74- private IList < PropertyInfo > _instancePropertyInfo ;
73+ private IList < PropertyInfo > _instancePropertyInfos ;
7574
7675 /// <summary>
7776 /// String Dictionary that contains the extra dynamic values
@@ -104,7 +103,6 @@ public Expando(object instance)
104103 Initialize ( instance ) ;
105104 }
106105
107-
108106 protected virtual void Initialize ( object instance )
109107 {
110108 _instance = instance ;
@@ -117,13 +115,13 @@ protected object WrappedObject
117115 get { return _instance ; }
118116 }
119117
120- IList < PropertyInfo > InstancePropertyInfo
118+ IList < PropertyInfo > InstancePropertyInfos
121119 {
122120 get
123121 {
124- if ( _instancePropertyInfo == null && _instance != null )
125- _instancePropertyInfo = _instance . GetType ( ) . Properties ( Flags . InstancePublicDeclaredOnly ) ;
126- return _instancePropertyInfo ;
122+ if ( _instancePropertyInfos == null && _instance != null )
123+ _instancePropertyInfos = Fasterflect . PropertyExtensions . Properties ( _instance . GetType ( ) , Fasterflect . Flags . InstancePublicDeclaredOnly ) ;
124+ return _instancePropertyInfos ;
127125 }
128126 }
129127
@@ -143,68 +141,76 @@ public override IEnumerable<string> GetDynamicMemberNames()
143141 /// <returns></returns>
144142 public override bool TryGetMember ( GetMemberBinder binder , out object result )
145143 {
146- result = null ;
147-
148- // first check the Properties collection for member
149- if ( Properties . Keys . Contains ( binder . Name ) )
150- {
151- result = Properties [ binder . Name ] ;
152- return true ;
153- }
154-
155-
156- // Next check for Public properties via Reflection
157- if ( _instance != null )
158- {
159- try
160- {
161- return GetProperty ( _instance , binder . Name , out result ) ;
162- }
163- catch { }
164- }
165-
166- // failed to retrieve a property
167- result = null ;
168- return false ;
144+ return TryGetMemberCore ( binder . Name , out result ) ;
169145 }
170146
147+ protected virtual bool TryGetMemberCore ( string name , out object result )
148+ {
149+ result = null ;
150+
151+ // first check the Properties collection for member
152+ if ( Properties . Keys . Contains ( name ) )
153+ {
154+ result = Properties [ name ] ;
155+ return true ;
156+ }
157+
158+ // Next check for public properties via Reflection
159+ if ( _instance != null )
160+ {
161+ try
162+ {
163+ return GetProperty ( _instance , name , out result ) ;
164+ }
165+ catch { }
166+ }
167+
168+ // failed to retrieve a property
169+ result = null ;
170+ return false ;
171+ }
171172
172- /// <summary>
173- /// Property setter implementation tries to retrieve value from instance
174- /// first then into this object
175- /// </summary>
176- /// <param name="binder"></param>
177- /// <param name="value"></param>
178- /// <returns></returns>
179- public override bool TrySetMember ( SetMemberBinder binder , object value )
180- {
181-
182- // first check to see if there's a native property to set
183- if ( _instance != null )
184- {
185- try
186- {
187- bool result = SetProperty ( _instance , binder . Name , value ) ;
188- if ( result )
189- return true ;
190- }
191- catch { }
192- }
193173
194- // no match - set or add to dictionary
195- Properties [ binder . Name ] = value ;
196- return true ;
174+ /// <summary>
175+ /// Property setter implementation tries to retrieve value from instance
176+ /// first then into this object
177+ /// </summary>
178+ /// <param name="binder"></param>
179+ /// <param name="value"></param>
180+ /// <returns></returns>
181+ public override bool TrySetMember ( SetMemberBinder binder , object value )
182+ {
183+ return TrySetMemberCore ( binder . Name , value ) ;
197184 }
198185
199- /// <summary>
200- /// Dynamic invocation method. Currently allows only for Reflection based
201- /// operation (no ability to add methods dynamically).
202- /// </summary>
203- /// <param name="binder"></param>
204- /// <param name="args"></param>
205- /// <param name="result"></param>
206- /// <returns></returns>
207- public override bool TryInvokeMember ( InvokeMemberBinder binder , object [ ] args , out object result )
186+ protected virtual bool TrySetMemberCore ( string name , object value )
187+ {
188+ // first check to see if there's a native property to set
189+ if ( _instance != null )
190+ {
191+ try
192+ {
193+ bool result = SetProperty ( _instance , name , value ) ;
194+ if ( result )
195+ return true ;
196+ }
197+ catch { }
198+ }
199+
200+ // no match - set or add to dictionary
201+ Properties [ name ] = value ;
202+ return true ;
203+ }
204+
205+ /// <summary>
206+ /// Dynamic invocation method. Currently allows only for Reflection based
207+ /// operation (no ability to add methods dynamically).
208+ /// </summary>
209+ /// <param name="binder"></param>
210+ /// <param name="args"></param>
211+ /// <param name="result"></param>
212+ /// <returns></returns>
213+ public override bool TryInvokeMember ( InvokeMemberBinder binder , object [ ] args , out object result )
208214 {
209215 if ( _instance != null )
210216 {
@@ -231,20 +237,27 @@ public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, o
231237 /// <returns></returns>
232238 protected bool GetProperty ( object instance , string name , out object result )
233239 {
234- if ( instance == null )
235- instance = this ;
236-
237- var pi = _instanceType . Property ( name , Flags . InstancePublic ) ;
240+ var pi = GetPropertyInfo ( name ) ;
238241 if ( pi != null )
239242 {
240- result = instance . GetPropertyValue ( pi . Name ) ;
243+ result = Fasterflect . PropertyExtensions . GetPropertyValue ( instance ?? this , pi . Name ) ;
241244 return true ;
242245 }
243246
244247 result = null ;
245248 return false ;
246249 }
247250
251+ /// <summary>
252+ /// Gets a <c>PropertyInfo</c> instance from the wrapped object
253+ /// </summary>
254+ /// <param name="name">Property name</param>
255+ protected PropertyInfo GetPropertyInfo ( string name )
256+ {
257+ var pi = Fasterflect . PropertyExtensions . Property ( _instanceType , name , Fasterflect . Flags . InstancePublic ) ;
258+ return pi ;
259+ }
260+
248261 /// <summary>
249262 /// Reflection helper method to set a property value
250263 /// </summary>
@@ -254,13 +267,10 @@ protected bool GetProperty(object instance, string name, out object result)
254267 /// <returns></returns>
255268 protected bool SetProperty ( object instance , string name , object value )
256269 {
257- if ( instance == null )
258- instance = this ;
259-
260- var pi = _instanceType . Property ( name , Flags . InstancePublic ) ;
270+ var pi = GetPropertyInfo ( name ) ;
261271 if ( pi != null )
262272 {
263- instance . SetPropertyValue ( pi . Name , value ) ;
273+ Fasterflect . PropertyInfoExtensions . Set ( pi , instance ?? this , value ) ;
264274 return true ;
265275 }
266276 return false ;
@@ -276,90 +286,67 @@ protected bool SetProperty(object instance, string name, object value)
276286 /// <returns></returns>
277287 protected bool InvokeMethod ( object instance , string name , object [ ] args , out object result )
278288 {
279- if ( instance == null )
280- instance = this ;
281-
282289 // Look at the instanceType
283- var mi = _instanceType . Method ( name , Flags . InstancePublic ) ;
284-
290+ var mi = Fasterflect . MethodExtensions . Method ( _instanceType , name , Fasterflect . Flags . InstancePublic ) ;
285291 if ( mi != null )
286292 {
287- result = _instance . CallMethod ( mi . Name , args ) ;
288- return true ;
293+ result = Fasterflect . MethodInfoExtensions . Call ( mi , instance ?? this , args ) ;
294+ return true ;
289295 }
290296
291297 result = null ;
292298 return false ;
293299 }
294300
295301
296- /// <summary>
297- /// Convenience method that provides a string Indexer
298- /// to the Properties collection AND the strongly typed
299- /// properties of the object by name.
300- ///
301- /// // dynamic
302- /// exp["Address"] = "112 nowhere lane";
303- /// // strong
304- /// var name = exp["StronglyTypedProperty"] as string;
305- /// </summary>
306- /// <remarks>
307- /// The getter checks the Properties dictionary first
308- /// then looks in PropertyInfo for properties.
309- /// The setter checks the instance properties before
310- /// checking the Properties dictionary.
311- /// </remarks>
312- /// <param name="key"></param>
313- ///
314- /// <returns></returns>
315- public object this [ string key ]
316- {
317- get
318- {
319- try
320- {
321- // try to get from properties collection first
322- return Properties [ key ] ;
323- }
324- catch ( KeyNotFoundException )
325- {
326- // try reflection on instanceType
327- object result = null ;
328- if ( GetProperty ( _instance , key , out result ) )
329- return result ;
330-
331- // no doesn't exist
332- throw ;
333- }
334- }
335- set
336- {
337- if ( Properties . ContainsKey ( key ) )
338- {
339- Properties [ key ] = value ;
340- return ;
341- }
342-
343- // check instance for existance of type first
344- var pi = _instanceType . Property ( key , Flags . Public ) ;
345- if ( pi != null )
346- SetProperty ( _instance , key , value ) ;
347- else
348- Properties [ key ] = value ;
349- }
350- }
302+ /// <summary>
303+ /// Convenience method that provides a string Indexer
304+ /// to the Properties collection AND the strongly typed
305+ /// properties of the object by name.
306+ ///
307+ /// // dynamic
308+ /// exp["Address"] = "112 nowhere lane";
309+ /// // strong
310+ /// var name = exp["StronglyTypedProperty"] as string;
311+ /// </summary>
312+ /// <remarks>
313+ /// The getter checks the Properties dictionary first
314+ /// then looks in PropertyInfo for properties.
315+ /// The setter checks the instance properties before
316+ /// checking the Properties dictionary.
317+ /// </remarks>
318+ /// <param name="key"></param>
319+ ///
320+ /// <returns></returns>
321+ public object this [ string key ]
322+ {
323+ get
324+ {
325+ object result = null ;
326+ if ( TryGetMemberCore ( key , out result ) )
327+ {
328+ return result ;
329+ }
330+
331+ throw new KeyNotFoundException ( ) ;
332+ }
333+ set
334+ {
335+ TrySetMemberCore ( key , value ) ;
336+ }
337+ }
351338
352339
353- /// <summary>
354- /// Returns and the properties of
355- /// </summary>
356- /// <param name="includeProperties"></param>
357- /// <returns></returns>
358- public IEnumerable < KeyValuePair < string , object > > GetProperties ( bool includeInstanceProperties = false )
340+ /// <summary>
341+ /// Returns all properties
342+ /// </summary>
343+ /// <param name="includeProperties"></param>
344+ /// <returns></returns>
345+ public IEnumerable < KeyValuePair < string , object > > GetProperties ( bool includeInstanceProperties = false )
359346 {
360347 if ( includeInstanceProperties && _instance != null )
361348 {
362- foreach ( var prop in this . InstancePropertyInfo )
349+ foreach ( var prop in this . InstancePropertyInfos )
363350 yield return new KeyValuePair < string , object > ( prop . Name , prop . GetValue ( _instance , null ) ) ;
364351 }
365352
@@ -388,13 +375,13 @@ public bool Contains(KeyValuePair<string, object> item, bool includeInstanceProp
388375 /// <returns></returns>
389376 public bool Contains ( string propertyName , bool includeInstanceProperties = false )
390377 {
391- bool res = Properties . ContainsKey ( propertyName ) ;
392- if ( res )
378+ bool contains = Properties . ContainsKey ( propertyName ) ;
379+ if ( contains )
393380 return true ;
394381
395382 if ( includeInstanceProperties && _instance != null )
396383 {
397- foreach ( var prop in this . InstancePropertyInfo )
384+ foreach ( var prop in this . InstancePropertyInfos )
398385 {
399386 if ( prop . Name == propertyName )
400387 return true ;
0 commit comments