CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
ManagedObjectBase.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="ManagedObjectBase.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Base class for an object that is serializable</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.Linq;
11using System.Linq.Expressions;
12using System.Reflection;
13using System.Text;
16using System.ComponentModel;
17using Csla.Reflection;
19
20namespace Csla.Core
21{
27 public abstract class ManagedObjectBase : MobileObject,
28 INotifyPropertyChanged
29 {
30 #region Field Manager
31
32 private FieldDataManager _fieldManager;
38 {
39 get
40 {
41 if (_fieldManager == null)
42 _fieldManager = new FieldDataManager(GetType());
43 return _fieldManager;
44 }
45 }
46
47 #endregion
48
49 #region Register Properties
50
67 protected static PropertyInfo<P> RegisterProperty<P>(Type objectType, PropertyInfo<P> info)
68 {
69 return Core.FieldManager.PropertyInfoManager.RegisterProperty<P>(objectType, info);
70 }
71
72
81 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression)
82 {
83 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
84
85 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name));
86 }
87
97 protected static PropertyInfo<P> RegisterProperty<T, P>(Expression<Func<T, object>> propertyLambdaExpression, P defaultValue)
98 {
99 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
100
101 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, reflectedPropertyInfo.Name, defaultValue));
102 }
103
113 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression, string friendlyName)
114 {
115 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
116
117 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, friendlyName));
118 }
119
130 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression, string friendlyName, P defaultValue)
131 {
132 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
133
134 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, friendlyName, defaultValue));
135 }
136
137 #endregion
138
139 #region Read Properties
140
155 {
156 return Utilities.CoerceValue<P>(typeof(F), null, ReadProperty<F>(propertyInfo));
157 }
158
167 protected P ReadProperty<P>(PropertyInfo<P> propertyInfo)
168 {
169 P result = default(P);
170 FieldManager.IFieldData data = FieldManager.GetFieldData(propertyInfo);
171 if (data != null)
172 {
173 var fd = data as FieldManager.IFieldData<P>;
174 if (fd != null)
175 result = fd.Value;
176 else
177 result = (P)data.Value;
178 }
179 else
180 {
181 result = propertyInfo.DefaultValue;
182 FieldManager.LoadFieldData<P>(propertyInfo, result);
183 }
184 return result;
185 }
186
192 protected virtual object ReadProperty(IPropertyInfo propertyInfo)
193 {
194 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
195 {
196 return MethodCaller.CallPropertyGetter(this, propertyInfo.Name);
197 }
198
199 object result = null;
200 var info = FieldManager.GetFieldData(propertyInfo);
201 if (info != null)
202 {
203 result = info.Value;
204 }
205 else
206 {
207 result = propertyInfo.DefaultValue;
208 FieldManager.LoadFieldData(propertyInfo, result);
209 }
210 return result;
211 }
212
213 #endregion
214
215 #region Load Properties
216
232 protected void LoadPropertyConvert<P, F>(PropertyInfo<P> propertyInfo, F newValue)
233 {
234 try
235 {
236 P oldValue = default(P);
237 var fieldData = FieldManager.GetFieldData(propertyInfo);
238 if (fieldData == null)
239 {
240 oldValue = propertyInfo.DefaultValue;
241 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
242 }
243 else
244 {
245 var fd = fieldData as FieldManager.IFieldData<P>;
246 if (fd != null)
247 oldValue = fd.Value;
248 else
249 oldValue = (P)fieldData.Value;
250 }
251 LoadPropertyValue<P>(propertyInfo, oldValue, Utilities.CoerceValue<P>(typeof(F), oldValue, newValue), false);
252 }
253 catch (Exception ex)
254 {
255 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
256 }
257 }
258
277 protected void LoadProperty<P>(PropertyInfo<P> propertyInfo, P newValue)
278 {
279 try
280 {
281 P oldValue = default(P);
282 var fieldData = FieldManager.GetFieldData(propertyInfo);
283 if (fieldData == null)
284 {
285 oldValue = propertyInfo.DefaultValue;
286 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
287 }
288 else
289 {
290 var fd = fieldData as FieldManager.IFieldData<P>;
291 if (fd != null)
292 oldValue = fd.Value;
293 else
294 oldValue = (P)fieldData.Value;
295 }
296 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, false);
297 }
298 catch (Exception ex)
299 {
300 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
301 }
302 }
303
304 private bool LoadPropertyMarkDirty<P>(PropertyInfo<P> propertyInfo, P newValue)
305 {
306 try
307 {
308 P oldValue = default(P);
309 var fieldData = FieldManager.GetFieldData(propertyInfo);
310 if (fieldData == null)
311 {
312 oldValue = propertyInfo.DefaultValue;
313 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
314 }
315 else
316 {
317 var fd = fieldData as FieldManager.IFieldData<P>;
318 if (fd != null)
319 oldValue = fd.Value;
320 else
321 oldValue = (P)fieldData.Value;
322 }
323 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, false);
324 return !oldValue.Equals(newValue);
325 }
326 catch (Exception ex)
327 {
328 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
329 }
330 }
331
332 private void LoadPropertyValue<P>(PropertyInfo<P> propertyInfo, P oldValue, P newValue, bool markDirty)
333 {
334 var valuesDiffer = false;
335 if (oldValue == null)
336 valuesDiffer = newValue != null;
337 else
338 valuesDiffer = !(oldValue.Equals(newValue));
339
340 if (valuesDiffer)
341 FieldManager.LoadFieldData<P>(propertyInfo, newValue);
342 }
343
359 protected virtual void LoadProperty(IPropertyInfo propertyInfo, object newValue)
360 {
361 var t = this.GetType();
362 var method = t.GetRuntimeMethods().FirstOrDefault(c => c.Name == "LoadProperty" && c.IsGenericMethod);
363 var gm = method.MakeGenericMethod(propertyInfo.Type);
364 var p = new object[] { propertyInfo, newValue };
365 gm.Invoke(this, p);
366 }
367
374 protected virtual bool LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
375 {
376 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
377 {
378 LoadProperty(propertyInfo, newValue);
379 return false;
380 }
381 var t = this.GetType();
382 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
383 var method = t.GetMethods(flags).FirstOrDefault(c => c.Name == "LoadPropertyMarkDirty" && c.IsGenericMethod);
384 var gm = method.MakeGenericMethod(propertyInfo.Type);
385 var p = new object[] { propertyInfo, newValue };
386 return (bool) gm.Invoke(this, p);
387 }
388
389 #endregion
390
391 #region INotifyPropertyChanged Members
392
393#if NETFX_CORE
397 public event PropertyChangedEventHandler PropertyChanged;
398
403 protected void OnPropertyChanged(string propertyName)
404 {
405 if (PropertyChanged != null)
406 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
407 }
408#else
409 [NonSerialized]
410 [NotUndoable]
411 private PropertyChangedEventHandler _propertyChanged;
412
413 event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
414 {
415 add { _propertyChanged = (PropertyChangedEventHandler)Delegate.Combine(_propertyChanged, value); }
416 remove { _propertyChanged = (PropertyChangedEventHandler)Delegate.Remove(_propertyChanged, value); }
417 }
418
423 protected void OnPropertyChanged(string propertyName)
424 {
425 if (_propertyChanged != null)
426 _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
427 }
428#endif
429
434 protected void OnPropertyChanged(IPropertyInfo propertyInfo)
435 {
436 OnPropertyChanged(propertyInfo.Name);
437 }
438
439 #endregion
440
441 #region MobileObject
442
449 protected override void OnGetChildren(SerializationInfo info, MobileFormatter formatter)
450 {
451 if (_fieldManager != null)
452 {
453 SerializationInfo child = formatter.SerializeObject(_fieldManager);
454 info.AddChild("_fieldManager", child.ReferenceId);
455 }
456
457 base.OnGetChildren(info, formatter);
458 }
459
466 protected override void OnSetChildren(SerializationInfo info, MobileFormatter formatter)
467 {
468 if (info.Children.ContainsKey("_fieldManager"))
469 {
470 int referenceId = info.Children["_fieldManager"].ReferenceId;
471 _fieldManager = (FieldDataManager)formatter.GetObject(referenceId);
472 }
473
474 base.OnSetChildren(info, formatter);
475 }
476
477 #endregion
478
479 #region OnDeserialized
480
481
482 [System.Runtime.Serialization.OnDeserialized()]
483 private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
484 {
485 OnDeserialized(context);
486 }
487
493 [EditorBrowsable(EditorBrowsableState.Advanced)]
494 protected virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
495 {
496 if (FieldManager != null)
497 FieldManager.SetPropertyList(this.GetType());
498 }
499
500 #endregion
501 }
502}
Manages properties and property data for a business object.
IFieldData GetFieldData(IPropertyInfo propertyInfo)
Gets the IFieldData object for a specific field.
Base class for an object that is serializable using SerializationFormatterFactory....
virtual bool LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
Loads the property vith new value and mark field dirty if value is changed.
virtual void LoadProperty(IPropertyInfo propertyInfo, object newValue)
Loads a property's managed field with the supplied value calling PropertyHasChanged if the value does...
void LoadProperty< P >(PropertyInfo< P > propertyInfo, P newValue)
Loads a property's managed field with the supplied value calling PropertyHasChanged if the value does...
void OnPropertyChanged(IPropertyInfo propertyInfo)
Raises the PropertyChanged event.
virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
This method is called on a newly deserialized object after deserialization is complete.
void LoadPropertyConvert< P, F >(PropertyInfo< P > propertyInfo, F newValue)
Loads a property's managed field with the supplied value calling PropertyHasChanged if the value does...
static PropertyInfo< P > RegisterProperty< P >(Type objectType, PropertyInfo< P > info)
Indicates that the specified property belongs to the type.
virtual object ReadProperty(IPropertyInfo propertyInfo)
Gets a property's value as a specified type.
P ReadProperty< P >(PropertyInfo< P > propertyInfo)
Gets a property's value as a specified type.
void OnPropertyChanged(string propertyName)
Raises the PropertyChanged event.
P ReadPropertyConvert< F, P >(PropertyInfo< F > propertyInfo)
Gets a property's value from the list of managed field values, converting the value to an appropriate...
override void OnGetChildren(SerializationInfo info, MobileFormatter formatter)
Override this method to manually retrieve child object data from the serializations stream.
FieldDataManager FieldManager
Gets a reference to the field mananger for this object.
static PropertyInfo< P > RegisterProperty< T, P >(Expression< Func< T, object > > propertyLambdaExpression)
Indicates that the specified property belongs to the business object type.
override void OnSetChildren(SerializationInfo info, MobileFormatter formatter)
Override this method to manually serialize child objects into the serialization stream.
Inherit from this base class to easily create a serializable class.
Definition: MobileObject.cs:20
Maintains metadata about a property.
virtual T DefaultValue
Gets the default initial value for the property.
string Name
Gets the property name value.
Exception indicating a failure to set a property's field.
Serializes and deserializes objects at the field level.
IMobileObject GetObject(int referenceId)
Gets a deserialized object based on the object's reference id within the serialization stream.
SerializationInfo SerializeObject(object obj)
Serializes an object into a SerializationInfo object.
Object containing the serialization data for a specific object.
int ReferenceId
Reference number for this object.
Dictionary< string, ChildData > Children
Dictionary containing child reference data.
void AddChild(string name, int referenceId)
Adds a child to the list of child references.
object Value
Gets or sets the field value.
Definition: IFieldData.cs:27
string Name
Gets the member name value.
Definition: IMemberInfo.cs:23
Maintains metadata about a property.
RelationshipTypes RelationshipType
Gets the relationship between the declaring object and the object reference in the property.
Type Type
Gets the type of the property.
object DefaultValue
Gets the default initial value for the property.
RelationshipTypes
List of valid relationship types between a parent object and another object through a managed propert...
@ Serializable
Prevents updating or inserting until the transaction is complete.