@@ -80,15 +80,54 @@ public AttrAttribute(string publicName, string internalName, bool isImmutable =
8080 /// Returns null if the attribute does not belong to the
8181 /// provided object.
8282 /// </summary>
83- public object GetValue ( object entity ) => PropertyInfo . GetValue ( entity ) ;
83+ public object GetValue ( object entity )
84+ {
85+ if ( entity == null )
86+ throw new InvalidOperationException ( "Cannot GetValue from null object." ) ;
87+
88+ var prop = GetResourceProperty ( entity ) ;
89+ return prop ? . GetValue ( entity ) ;
90+ }
8491
8592 /// <summary>
8693 /// Sets the value of the attribute on the given object.
8794 /// </summary>
8895 public void SetValue ( object entity , object newValue )
8996 {
90- var convertedValue = TypeHelper . ConvertType ( newValue , PropertyInfo . PropertyType ) ;
91- PropertyInfo . SetValue ( entity , convertedValue ) ;
97+ if ( entity == null )
98+ throw new InvalidOperationException ( "Cannot SetValue on null object." ) ;
99+
100+ var prop = GetResourceProperty ( entity ) ;
101+ if ( prop != null )
102+ {
103+ var convertedValue = TypeHelper . ConvertType ( newValue , prop . PropertyType ) ;
104+ prop . SetValue ( entity , convertedValue ) ;
105+ }
106+ }
107+
108+ private PropertyInfo GetResourceProperty ( object resource )
109+ {
110+ // There are some scenarios, especially ones where users are using a different
111+ // data model than view model, where they may use a repository implmentation
112+ // that does not match the deserialized type. For now, we will continue to support
113+ // this use case.
114+ var targetType = resource . GetType ( ) ;
115+ if ( targetType != PropertyInfo . DeclaringType )
116+ {
117+ var propertyInfo = resource
118+ . GetType ( )
119+ . GetProperty ( InternalAttributeName ) ;
120+
121+ return propertyInfo ;
122+
123+ // TODO: this should throw but will be a breaking change in some cases
124+ //if (propertyInfo == null)
125+ // throw new InvalidOperationException(
126+ // $"'{targetType}' does not contain a member named '{InternalAttributeName}'." +
127+ // $"There is also a mismatch in target types. Expected '{PropertyInfo.DeclaringType}' but instead received '{targetType}'.");
128+ }
129+
130+ return PropertyInfo ;
92131 }
93132
94133 /// <summary>
0 commit comments