CSLA.NET 6.0.0
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.Linq;
10using System.Linq.Expressions;
11using System.Reflection;
13using System.ComponentModel;
14using Csla.Reflection;
16using System.Collections.Generic;
17using System.Threading.Tasks;
18
19namespace Csla.Core
20{
26 public abstract class ManagedObjectBase : MobileObject,
27 INotifyPropertyChanged,
28 IManageProperties,
30 IUseFieldManager
31 {
35 protected ApplicationContext ApplicationContext { get; private set; }
37
38 #region Field Manager
39
40 private FieldDataManager _fieldManager;
46 {
47 get
48 {
49 if (_fieldManager == null)
50 _fieldManager = new FieldDataManager(ApplicationContext, GetType());
51 return _fieldManager;
52 }
53 }
54
55 FieldDataManager IUseFieldManager.FieldManager => FieldManager;
56
57 #endregion
58
59 #region Register Properties
60
77 protected static PropertyInfo<P> RegisterProperty<P>(Type objectType, PropertyInfo<P> info)
78 {
79 return Core.FieldManager.PropertyInfoManager.RegisterProperty<P>(objectType, info);
80 }
81
82
91 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression)
92 {
93 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
94
95 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name));
96 }
97
107 protected static PropertyInfo<P> RegisterProperty<T, P>(Expression<Func<T, object>> propertyLambdaExpression, P defaultValue)
108 {
109 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
110
111 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, reflectedPropertyInfo.Name, defaultValue));
112 }
113
123 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression, string friendlyName)
124 {
125 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
126
127 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, friendlyName));
128 }
129
140 protected static PropertyInfo<P> RegisterProperty<T,P>(Expression<Func<T, object>> propertyLambdaExpression, string friendlyName, P defaultValue)
141 {
142 PropertyInfo reflectedPropertyInfo = Reflect<T>.GetProperty(propertyLambdaExpression);
143
144 return RegisterProperty(typeof(T), Csla.Core.FieldManager.PropertyInfoFactory.Factory.Create<P>(typeof(T), reflectedPropertyInfo.Name, friendlyName, defaultValue));
145 }
146
147 #endregion
148
149 #region Read Properties
150
165 {
166 return Utilities.CoerceValue<P>(typeof(F), null, ReadProperty<F>(propertyInfo));
167 }
168
177 protected P ReadProperty<P>(PropertyInfo<P> propertyInfo)
178 {
179 P result = default(P);
180 FieldManager.IFieldData data = FieldManager.GetFieldData(propertyInfo);
181 if (data != null)
182 {
183 var fd = data as FieldManager.IFieldData<P>;
184 if (fd != null)
185 result = fd.Value;
186 else
187 result = (P)data.Value;
188 }
189 else
190 {
191 result = propertyInfo.DefaultValue;
192 FieldManager.LoadFieldData<P>(propertyInfo, result);
193 }
194 return result;
195 }
196
202 protected virtual object ReadProperty(IPropertyInfo propertyInfo)
203 {
204 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
205 {
206 return MethodCaller.CallPropertyGetter(this, propertyInfo.Name);
207 }
208
209 object result = null;
210 var info = FieldManager.GetFieldData(propertyInfo);
211 if (info != null)
212 {
213 result = info.Value;
214 }
215 else
216 {
217 result = propertyInfo.DefaultValue;
218 FieldManager.LoadFieldData(propertyInfo, result);
219 }
220 return result;
221 }
222
223 #endregion
224
225 #region Load Properties
226
242 protected void LoadPropertyConvert<P, F>(PropertyInfo<P> propertyInfo, F newValue)
243 {
244 try
245 {
246 P oldValue = default(P);
247 var fieldData = FieldManager.GetFieldData(propertyInfo);
248 if (fieldData == null)
249 {
250 oldValue = propertyInfo.DefaultValue;
251 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
252 }
253 else
254 {
255 var fd = fieldData as FieldManager.IFieldData<P>;
256 if (fd != null)
257 oldValue = fd.Value;
258 else
259 oldValue = (P)fieldData.Value;
260 }
261 LoadPropertyValue<P>(propertyInfo, oldValue, Utilities.CoerceValue<P>(typeof(F), oldValue, newValue), false);
262 }
263 catch (Exception ex)
264 {
265 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
266 }
267 }
268
287 protected void LoadProperty<P>(PropertyInfo<P> propertyInfo, P newValue)
288 {
289 try
290 {
291 P oldValue = default(P);
292 var fieldData = FieldManager.GetFieldData(propertyInfo);
293 if (fieldData == null)
294 {
295 oldValue = propertyInfo.DefaultValue;
296 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
297 }
298 else
299 {
300 var fd = fieldData as FieldManager.IFieldData<P>;
301 if (fd != null)
302 oldValue = fd.Value;
303 else
304 oldValue = (P)fieldData.Value;
305 }
306 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, false);
307 }
308 catch (Exception ex)
309 {
310 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
311 }
312 }
313
314 private bool LoadPropertyMarkDirty<P>(PropertyInfo<P> propertyInfo, P newValue)
315 {
316 try
317 {
318 P oldValue = default(P);
319 var fieldData = FieldManager.GetFieldData(propertyInfo);
320 if (fieldData == null)
321 {
322 oldValue = propertyInfo.DefaultValue;
323 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
324 }
325 else
326 {
327 var fd = fieldData as FieldManager.IFieldData<P>;
328 if (fd != null)
329 oldValue = fd.Value;
330 else
331 oldValue = (P)fieldData.Value;
332 }
333 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, false);
334 return !oldValue.Equals(newValue);
335 }
336 catch (Exception ex)
337 {
338 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message));
339 }
340 }
341
342 private void LoadPropertyValue<P>(PropertyInfo<P> propertyInfo, P oldValue, P newValue, bool markDirty)
343 {
344 var valuesDiffer = false;
345 if (oldValue == null)
346 valuesDiffer = newValue != null;
347 else
348 valuesDiffer = !(oldValue.Equals(newValue));
349
350 if (valuesDiffer)
351 FieldManager.LoadFieldData<P>(propertyInfo, newValue);
352 }
353
369 protected virtual void LoadProperty(IPropertyInfo propertyInfo, object newValue)
370 {
371 var t = this.GetType();
372 var method = t.GetRuntimeMethods().FirstOrDefault(c => c.Name == "LoadProperty" && c.IsGenericMethod);
373 var gm = method.MakeGenericMethod(propertyInfo.Type);
374 var p = new object[] { propertyInfo, newValue };
375 gm.Invoke(this, p);
376 }
377
384 protected virtual bool LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
385 {
386 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
387 {
388 LoadProperty(propertyInfo, newValue);
389 return false;
390 }
391 var t = this.GetType();
392 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
393 var method = t.GetMethods(flags).FirstOrDefault(c => c.Name == "LoadPropertyMarkDirty" && c.IsGenericMethod);
394 var gm = method.MakeGenericMethod(propertyInfo.Type);
395 var p = new object[] { propertyInfo, newValue };
396 return (bool) gm.Invoke(this, p);
397 }
398
399 #endregion
400
401 #region INotifyPropertyChanged Members
402
403#if NETFX_CORE
407 public event PropertyChangedEventHandler PropertyChanged;
408
413 protected void OnPropertyChanged(string propertyName)
414 {
415 if (PropertyChanged != null)
416 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
417 }
418#else
419 [NonSerialized]
420 [NotUndoable]
421 private PropertyChangedEventHandler _propertyChanged;
422
423 event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
424 {
425 add { _propertyChanged = (PropertyChangedEventHandler)Delegate.Combine(_propertyChanged, value); }
426 remove { _propertyChanged = (PropertyChangedEventHandler)Delegate.Remove(_propertyChanged, value); }
427 }
428
433 protected void OnPropertyChanged(string propertyName)
434 {
435 if (_propertyChanged != null)
436 _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
437 }
438#endif
439
444 protected void OnPropertyChanged(IPropertyInfo propertyInfo)
445 {
446 OnPropertyChanged(propertyInfo.Name);
447 }
448
449 #endregion
450
451 #region MobileObject
452
459 protected override void OnGetChildren(SerializationInfo info, MobileFormatter formatter)
460 {
461 if (_fieldManager != null)
462 {
463 SerializationInfo child = formatter.SerializeObject(_fieldManager);
464 info.AddChild("_fieldManager", child.ReferenceId);
465 }
466
467 base.OnGetChildren(info, formatter);
468 }
469
476 protected override void OnSetChildren(SerializationInfo info, MobileFormatter formatter)
477 {
478 if (info.Children.ContainsKey("_fieldManager"))
479 {
480 int referenceId = info.Children["_fieldManager"].ReferenceId;
481 _fieldManager = (FieldDataManager)formatter.GetObject(referenceId);
482 }
483
484 base.OnSetChildren(info, formatter);
485 }
486
487 #endregion
488
489 #region OnDeserialized
490
491
492 [System.Runtime.Serialization.OnDeserialized()]
493 private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
494 {
495 OnDeserialized(context);
496 }
497
503 [EditorBrowsable(EditorBrowsableState.Advanced)]
504 protected virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
505 {
506 if (FieldManager != null)
507 FieldManager.SetPropertyList(this.GetType());
508 }
509
510 #endregion
511
512 bool IManageProperties.FieldExists(IPropertyInfo property) => FieldManager.FieldExists(property);
513 List<IPropertyInfo> IManageProperties.GetManagedProperties() => FieldManager.GetRegisteredProperties();
514 object IManageProperties.GetProperty(IPropertyInfo propertyInfo) => throw new NotImplementedException();
515 object IManageProperties.LazyGetProperty<P>(PropertyInfo<P> propertyInfo, Func<P> valueGenerator) => throw new NotImplementedException();
516 object IManageProperties.LazyGetPropertyAsync<P>(PropertyInfo<P> propertyInfo, Task<P> factory) => throw new NotImplementedException();
517 object IManageProperties.ReadProperty(IPropertyInfo propertyInfo) => ReadProperty(propertyInfo);
518 P IManageProperties.ReadProperty<P>(PropertyInfo<P> propertyInfo) => ReadProperty(propertyInfo);
519 P IManageProperties.LazyReadProperty<P>(PropertyInfo<P> propertyInfo, Func<P> valueGenerator) => throw new NotImplementedException();
520 P IManageProperties.LazyReadPropertyAsync<P>(PropertyInfo<P> propertyInfo, Task<P> factory) => throw new NotImplementedException();
521 void IManageProperties.SetProperty(IPropertyInfo propertyInfo, object newValue) => throw new NotImplementedException();
522 void IManageProperties.LoadProperty(IPropertyInfo propertyInfo, object newValue) => LoadProperty(propertyInfo, newValue);
523 bool IManageProperties.LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue) => throw new NotImplementedException();
524 void IManageProperties.LoadProperty<P>(PropertyInfo<P> propertyInfo, P newValue) => LoadProperty(propertyInfo, newValue);
525 List<object> IManageProperties.GetChildren() => FieldManager.GetChildren();
526 bool IManageProperties.HasManagedProperties => true;
527 }
528}
Provides consistent context information between the client and server DataPortal objects.
Manages properties and property data for a business object.
List< IPropertyInfo > GetRegisteredProperties()
Returns a copy of the property list for the business object.
IFieldData GetFieldData(IPropertyInfo propertyInfo)
Gets the IFieldData object for a specific field.
bool FieldExists(IPropertyInfo propertyInfo)
Returns a value indicating whether an IFieldData entry exists for the specified property.
List< object > GetChildren()
Returns a list of all child objects contained in the list of fields.
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...
ApplicationContext ApplicationContext
Gets the current ApplicationContext.
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.
Implement if a class requires access to the CSLA ApplicationContext type.
ApplicationContext ApplicationContext
Gets or sets the current ApplicationContext object.
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.