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.
Core/BusinessBase.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="BusinessBase.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>This is the non-generic base class from which most</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Concurrent;
10using System.Diagnostics;
11using System.Linq;
12using System.Collections.Generic;
13using System.ComponentModel;
14using System.Threading.Tasks;
15using Csla.Properties;
16using System.Collections.Specialized;
17using System.ComponentModel.DataAnnotations;
18using System.Collections.ObjectModel;
20using Csla.Reflection;
21using Csla.Server;
22using Csla.Security;
24using Csla.Rules;
25using System.Security;
27using System.Reflection;
28using System.Collections;
29
30namespace Csla.Core
31{
32
37#if TESTING
38 [System.Diagnostics.DebuggerStepThrough]
39#endif
41 public abstract class BusinessBase : UndoableBase,
43 IEditableObject,
44 ICloneable,
46 IParent,
47 IDataPortalTarget,
48 IManageProperties,
49 Rules.IHostRules,
54 IDataErrorInfo,
55 INotifyDataErrorInfo,
56 IUseFieldManager,
57 IUseBusinessRules
58 {
59
63 protected BusinessBase()
64 { }
65
70 protected override void OnApplicationContextSet()
71 {
72 InitializeIdentity();
73 Initialize();
74 InitializeBusinessRules();
75 }
76
77 #region Initialize
78
84 protected virtual void Initialize()
85 { /* allows subclass to initialize events before any other activity occurs */ }
86
87 #endregion
88
89 #region Identity
90
91 private int _identity = -1;
92
94 {
95 get { return _identity; }
96 }
97
98 private void InitializeIdentity()
99 {
100 _identity = ((IParent)this).GetNextIdentity(_identity);
101 }
102
103 [NonSerialized]
104 [NotUndoable]
105 private IdentityManager _identityManager;
106
107 int IParent.GetNextIdentity(int current)
108 {
109 if (this.Parent != null)
110 {
111 return this.Parent.GetNextIdentity(current);
112 }
113 else
114 {
115 if (_identityManager == null)
116 _identityManager = new IdentityManager();
117 return _identityManager.GetNextIdentity(current);
118 }
119 }
120
121 #endregion
122
123 #region Parent/Child link
124
125 [NotUndoable]
126 [NonSerialized]
127 private IParent _parent;
128
136 [Browsable(false)]
137 [Display(AutoGenerateField = false)]
138 [ScaffoldColumn(false)]
139 [EditorBrowsable(EditorBrowsableState.Advanced)]
140 public Core.IParent Parent
141 {
142 get { return _parent; }
143 }
144
151 protected virtual void SetParent(Core.IParent parent)
152 {
153 _parent = parent;
154 _identityManager = null;
155 InitializeIdentity();
156 }
157
158 #endregion
159
160 #region IsNew, IsDeleted, IsDirty, IsSavable
161
162 // keep track of whether we are new, deleted or dirty
163 private bool _isNew = true;
164 private bool _isDeleted;
165 private bool _isDirty = true;
166
180 [Browsable(false)]
181 [Display(AutoGenerateField = false)]
182 [ScaffoldColumn(false)]
183 public bool IsNew
184 {
185 get { return _isNew; }
186 }
187
202 [Browsable(false)]
203 [Display(AutoGenerateField = false)]
204 [ScaffoldColumn(false)]
205 public bool IsDeleted
206 {
207 get { return _isDeleted; }
208 }
209
229 [Browsable(false)]
230 [Display(AutoGenerateField = false)]
231 [ScaffoldColumn(false)]
232 public virtual bool IsDirty
233 {
234 get { return IsSelfDirty || (_fieldManager != null && FieldManager.IsDirty()); }
235 }
236
254 [Browsable(false)]
255 [Display(AutoGenerateField = false)]
256 [ScaffoldColumn(false)]
257 public virtual bool IsSelfDirty
258 {
259 get { return _isDirty; }
260 }
261
277 protected virtual void MarkNew()
278 {
279 _isNew = true;
280 _isDeleted = false;
281 MetaPropertyHasChanged("IsNew");
282 MetaPropertyHasChanged("IsDeleted");
283 MarkDirty();
284 }
285
304 protected virtual void MarkOld()
305 {
306 _isNew = false;
307 MetaPropertyHasChanged("IsNew");
308 MarkClean();
309 }
310
320 protected void MarkDeleted()
321 {
322 _isDeleted = true;
323 MetaPropertyHasChanged("IsDeleted");
324 MarkDirty();
325 }
326
344 protected void MarkDirty()
345 {
346 MarkDirty(false);
347 }
348
356 [EditorBrowsable(EditorBrowsableState.Advanced)]
357 protected void MarkDirty(bool suppressEvent)
358 {
359 bool old = _isDirty;
360 _isDirty = true;
361 if (!suppressEvent)
363 if (_isDirty != old)
364 {
365 MetaPropertyHasChanged("IsSelfDirty");
366 MetaPropertyHasChanged("IsDirty");
367 MetaPropertyHasChanged("IsSavable");
368 }
369 }
370
383 protected virtual void PropertyHasChanged(Csla.Core.IPropertyInfo property)
384 {
385 MarkDirty(true);
386 CheckPropertyRules(property);
387 }
388
389 private void PropertyHasChanged(string propertyName)
390 {
392 }
393
398 protected virtual void MetaPropertyHasChanged(string name)
399 {
402 }
403
408 [EditorBrowsable(EditorBrowsableState.Advanced)]
409 protected virtual void CheckPropertyRules(IPropertyInfo property)
410 {
411 var propertyNames = BusinessRules.CheckRules(property);
413 OnPropertyChanged(property);
414 else
415 foreach (var name in propertyNames)
416 OnPropertyChanged(name);
417 }
418
422 protected virtual void CheckObjectRules()
423 {
424 var propertyNames = BusinessRules.CheckObjectRules();
426 {
428 }
429 else
430 foreach (var name in propertyNames)
431 OnPropertyChanged(name);
432 }
433
434
435
443 [EditorBrowsable(EditorBrowsableState.Advanced)]
444 protected void MarkClean()
445 {
446 _isDirty = false;
447 if (_fieldManager != null)
448 FieldManager.MarkClean();
450 MetaPropertyHasChanged("IsSelfDirty");
451 MetaPropertyHasChanged("IsDirty");
452 MetaPropertyHasChanged("IsSavable");
453 }
454
466 [Browsable(false)]
467 [Display(AutoGenerateField = false)]
468 [ScaffoldColumn(false)]
469 public virtual bool IsSavable
470 {
471 get
472 {
473 bool auth;
474 if (IsDeleted)
475 auth = Csla.Rules.BusinessRules.HasPermission(ApplicationContext, Rules.AuthorizationActions.DeleteObject, this);
476 else if (IsNew)
477 auth = Csla.Rules.BusinessRules.HasPermission(ApplicationContext, Rules.AuthorizationActions.CreateObject, this);
478 else
479 auth = Csla.Rules.BusinessRules.HasPermission(ApplicationContext, Rules.AuthorizationActions.EditObject, this);
480 return (auth && IsDirty && IsValid && !IsBusy);
481 }
482 }
483
484 #endregion
485
486 #region Authorization
487
488 [NotUndoable]
489 [NonSerialized]
490 private ConcurrentDictionary<string, bool> _readResultCache;
491 [NotUndoable]
492 [NonSerialized]
493 private ConcurrentDictionary<string, bool> _writeResultCache;
494 [NotUndoable]
495 [NonSerialized]
496 private ConcurrentDictionary<string, bool> _executeResultCache;
497 [NotUndoable]
498 [NonSerialized]
499 private System.Security.Principal.IPrincipal _lastPrincipal;
500
506 [EditorBrowsable(EditorBrowsableState.Advanced)]
507 public virtual bool CanReadProperty(Csla.Core.IPropertyInfo property)
508 {
509 var result = true;
510
511 VerifyAuthorizationCache();
512
513 if (!_readResultCache.TryGetValue(property.Name, out result))
514 {
515 result = BusinessRules.HasPermission(ApplicationContext, AuthorizationActions.ReadProperty, property);
516 if (BusinessRules.CachePermissionResult(AuthorizationActions.ReadProperty, property))
517 {
518 // store value in cache
519 _readResultCache.AddOrUpdate(property.Name, result, (a,b) => { return result; });
520 }
521 }
522 return result;
523 }
524
533 [EditorBrowsable(EditorBrowsableState.Advanced)]
534 public bool CanReadProperty(Csla.Core.IPropertyInfo property, bool throwOnFalse)
535 {
536 bool result = CanReadProperty(property);
537 if (throwOnFalse && result == false)
538 {
540 String.Format("{0} ({1})",
541 Resources.PropertyGetNotAllowed, property.Name));
542 throw ex;
543 }
544 return result;
545 }
546
552 [EditorBrowsable(EditorBrowsableState.Advanced)]
553 public bool CanReadProperty(string propertyName)
554 {
555 return CanReadProperty(propertyName, false);
556 }
557
565 private bool CanReadProperty(string propertyName, bool throwOnFalse)
566 {
567 var propertyInfo = FieldManager.GetRegisteredProperties().FirstOrDefault(p => p.Name == propertyName);
568 if (propertyInfo == null)
569 {
570 Trace.TraceError("CanReadProperty: {0} is not a registered property of {1}.{2}", propertyName, this.GetType().Namespace, this.GetType().Name);
571 return true;
572 }
573 return CanReadProperty(propertyInfo, throwOnFalse);
574 }
575
581 [EditorBrowsable(EditorBrowsableState.Advanced)]
582 public virtual bool CanWriteProperty(Csla.Core.IPropertyInfo property)
583 {
584 bool result = true;
585
586 VerifyAuthorizationCache();
587
588 if (!_writeResultCache.TryGetValue(property.Name, out result))
589 {
590 result = BusinessRules.HasPermission(ApplicationContext, AuthorizationActions.WriteProperty, property);
591 if (BusinessRules.CachePermissionResult(AuthorizationActions.WriteProperty, property))
592 {
593 // store value in cache
594 _writeResultCache.AddOrUpdate(property.Name, result, (a, b) => { return result; });
595 }
596 }
597 return result;
598 }
599
608 [EditorBrowsable(EditorBrowsableState.Advanced)]
609 public bool CanWriteProperty(Csla.Core.IPropertyInfo property, bool throwOnFalse)
610 {
611 bool result = CanWriteProperty(property);
612 if (throwOnFalse && result == false)
613 {
615 String.Format("{0} ({1})", Resources.PropertySetNotAllowed, property.Name));
616 throw ex;
617 }
618 return result;
619 }
620
626 [EditorBrowsable(EditorBrowsableState.Advanced)]
627 public bool CanWriteProperty(string propertyName)
628 {
629 return CanWriteProperty(propertyName, false);
630 }
631
639 private bool CanWriteProperty(string propertyName, bool throwOnFalse)
640 {
641 var propertyInfo = FieldManager.GetRegisteredProperties().FirstOrDefault(p => p.Name == propertyName);
642 if (propertyInfo == null)
643 {
644 Trace.TraceError("CanReadProperty: {0} is not a registered property of {1}.{2}", propertyName, this.GetType().Namespace, this.GetType().Name);
645 return true;
646 }
647 return CanWriteProperty(propertyInfo, throwOnFalse);
648 }
649
650 private void VerifyAuthorizationCache()
651 {
652 if (_readResultCache == null)
653 _readResultCache = new ConcurrentDictionary<string, bool>();
654 if (_writeResultCache == null)
655 _writeResultCache = new ConcurrentDictionary<string, bool>();
656 if (_executeResultCache == null)
657 _executeResultCache = new ConcurrentDictionary<string, bool>();
658 if (!ReferenceEquals(ApplicationContext.User, _lastPrincipal))
659 {
660 // the principal has changed - reset the cache
661 _readResultCache.Clear();
662 _writeResultCache.Clear();
663 _executeResultCache.Clear();
664 _lastPrincipal = ApplicationContext.User;
665 }
666 }
667
674 [EditorBrowsable(EditorBrowsableState.Advanced)]
675 public virtual bool CanExecuteMethod(Csla.Core.IMemberInfo method)
676 {
677 bool result = true;
678
679 VerifyAuthorizationCache();
680
681 if (!_executeResultCache.TryGetValue(method.Name, out result))
682 {
685 {
686 // store value in cache
687 _executeResultCache.AddOrUpdate(method.Name, result, (a, b) => { return result; });
688 }
689 }
690 return result;
691 }
692
701 [EditorBrowsable(EditorBrowsableState.Advanced)]
702 public bool CanExecuteMethod(Csla.Core.IMemberInfo method, bool throwOnFalse)
703 {
704
705 bool result = CanExecuteMethod(method);
706 if (throwOnFalse && result == false)
707 {
709 new Csla.Security.SecurityException(string.Format("{0} ({1})", Properties.Resources.MethodExecuteNotAllowed, method.Name));
710 throw ex;
711 }
712 return result;
713
714 }
715
716
723 [EditorBrowsable(EditorBrowsableState.Advanced)]
724 public virtual bool CanExecuteMethod(string methodName)
725 {
726 return CanExecuteMethod(methodName, false);
727 }
728
729 private bool CanExecuteMethod(string methodName, bool throwOnFalse)
730 {
731
732 bool result = CanExecuteMethod(new MethodInfo(methodName));
733 if (throwOnFalse && result == false)
734 {
735 Csla.Security.SecurityException ex = new Csla.Security.SecurityException(string.Format("{0} ({1})", Properties.Resources.MethodExecuteNotAllowed, methodName));
736 throw ex;
737 }
738 return result;
739 }
740
741#endregion
742
743#region System.ComponentModel.IEditableObject
744
745 private bool _neverCommitted = true;
746 [NotUndoable]
747 private bool _disableIEditableObject;
748
765 [EditorBrowsable(EditorBrowsableState.Advanced)]
767 {
768 get
769 {
770 return _disableIEditableObject;
771 }
772 set
773 {
774 _disableIEditableObject = value;
775 }
776 }
777
786 void System.ComponentModel.IEditableObject.BeginEdit()
787 {
788 if (!_disableIEditableObject && !BindingEdit)
789 {
790 BindingEdit = true;
791 BeginEdit();
792 }
793 }
794
805 void System.ComponentModel.IEditableObject.CancelEdit()
806 {
807 if (!_disableIEditableObject && BindingEdit)
808 {
809 CancelEdit();
810 BindingEdit = false;
811 if (IsNew && _neverCommitted && EditLevel <= EditLevelAdded)
812 {
813 // we're new and no EndEdit or ApplyEdit has ever been
814 // called on us, and now we've been cancelled back to
815 // where we were added so we should have ourselves
816 // removed from the parent collection
817 if (Parent != null)
818 Parent.RemoveChild(this);
819 }
820 }
821 }
822
833 void System.ComponentModel.IEditableObject.EndEdit()
834 {
835 if (!_disableIEditableObject && BindingEdit)
836 {
837 ApplyEdit();
838 BindingEdit = false;
839 }
840 }
841
842#endregion
843
844#region Begin/Cancel/ApplyEdit
845
864 public void BeginEdit()
865 {
866 CopyState(this.EditLevel + 1);
867 }
868
878 public void CancelEdit()
879 {
880 UndoChanges(this.EditLevel - 1);
881 }
882
891 protected override void UndoChangesComplete()
892 {
893 BusinessRules.SetTarget(this);
894 InitializeBusinessRules();
896 base.UndoChangesComplete();
897 }
898
907 public void ApplyEdit()
908 {
909 _neverCommitted = false;
910 AcceptChanges(this.EditLevel - 1);
911 //Next line moved to IEditableObject.ApplyEdit
912 //BindingEdit = false;
913 }
914
919 protected override void AcceptChangesComplete()
920 {
921 BindingEdit = false;
922 base.AcceptChangesComplete();
923
924 // !!!! Will trigger Save here when using DynamicListBase template
925 if (Parent != null)
927 }
928
929#endregion
930
931#region IsChild
932
933 [NotUndoable]
934 private bool _isChild;
935
939 [Browsable(false)]
940 [Display(AutoGenerateField = false)]
941 [ScaffoldColumn(false)]
942 public bool IsChild
943 {
944 get { return _isChild; }
945 }
946
950 protected void MarkAsChild()
951 {
952 _identity = -1;
953 _isChild = true;
954 }
955
956#endregion
957
958#region Delete
959
975 public virtual void Delete()
976 {
977 if (this.IsChild)
978 throw new NotSupportedException(Resources.ChildDeleteException);
979
980 MarkDeleted();
981 }
982
987 internal void DeleteChild()
988 {
989 if (!this.IsChild)
990 throw new NotSupportedException(Resources.NoDeleteRootException);
991
992 BindingEdit = false;
993 MarkDeleted();
994 }
995
996#endregion
997
998#region Edit Level Tracking (child only)
999
1000 // we need to keep track of the edit
1001 // level when we weere added so if the user
1002 // cancels below that level we can be destroyed
1003 [NotUndoable]
1004 private int _editLevelAdded;
1005
1014 internal int EditLevelAdded
1015 {
1016 get { return _editLevelAdded; }
1017 set { _editLevelAdded = value; }
1018 }
1019
1020 int IUndoableObject.EditLevel
1021 {
1022 get
1023 {
1024 return this.EditLevel;
1025 }
1026 }
1027
1028#endregion
1029
1030#region ICloneable
1031
1032 object ICloneable.Clone()
1033 {
1034 return GetClone();
1035 }
1036
1043 [EditorBrowsable(EditorBrowsableState.Advanced)]
1044 protected virtual object GetClone()
1045 {
1046 return Core.ObjectCloner.GetInstance(ApplicationContext).Clone(this);
1047 }
1048
1049#endregion
1050
1051#region BusinessRules, IsValid
1052
1053 [NonSerialized]
1054 [NotUndoable]
1055 private EventHandler _validationCompleteHandlers;
1056
1060 public event EventHandler ValidationComplete
1061 {
1062 add
1063 {
1064 _validationCompleteHandlers = (EventHandler)
1065 System.Delegate.Combine(_validationCompleteHandlers, value);
1066 }
1067 remove
1068 {
1069 _validationCompleteHandlers = (EventHandler)
1070 System.Delegate.Remove(_validationCompleteHandlers, value);
1071 }
1072 }
1073
1077 [EditorBrowsable(EditorBrowsableState.Never)]
1078 protected virtual void OnValidationComplete()
1079 {
1080 if (_validationCompleteHandlers != null)
1081 _validationCompleteHandlers(this, EventArgs.Empty);
1082 }
1083
1084 private void InitializeBusinessRules()
1085 {
1086 var rules = BusinessRuleManager.GetRulesForType(this.GetType());
1087 if (!rules.Initialized)
1088 lock (rules)
1089 if (!rules.Initialized)
1090 {
1091 try
1092 {
1094 rules.Initialized = true;
1095 }
1096 catch (Exception)
1097 {
1098 BusinessRuleManager.CleanupRulesForType(this.GetType());
1099 throw; // and rethrow exception
1100 }
1101 }
1102 }
1103
1104 private Csla.Rules.BusinessRules _businessRules;
1105
1115 {
1116 get
1117 {
1118 if (_businessRules == null)
1119 _businessRules = new BusinessRules(ApplicationContext, this);
1120 else if (_businessRules.Target == null)
1121 _businessRules.SetTarget(this);
1122 return _businessRules;
1123 }
1124 }
1125
1126 BusinessRules IUseBusinessRules.BusinessRules => BusinessRules;
1127
1132 [EditorBrowsable(EditorBrowsableState.Never)]
1134 {
1135 return BusinessRules.TypeRules;
1136 }
1137
1138 void IHostRules.RuleStart(IPropertyInfo property)
1139 {
1140 OnBusyChanged(new BusyChangedEventArgs(property.Name, true));
1141 }
1142
1143 void IHostRules.RuleComplete(IPropertyInfo property)
1144 {
1145 OnPropertyChanged(property);
1146 OnBusyChanged(new BusyChangedEventArgs(property.Name, false));
1147 MetaPropertyHasChanged("IsSelfValid");
1148 MetaPropertyHasChanged("IsValid");
1149 MetaPropertyHasChanged("IsSavable");
1150 }
1151
1152 void IHostRules.RuleComplete(string property)
1153 {
1154 OnPropertyChanged(property);
1155 MetaPropertyHasChanged("IsSelfValid");
1156 MetaPropertyHasChanged("IsValid");
1157 MetaPropertyHasChanged("IsSavable");
1158 }
1159
1160 void Rules.IHostRules.AllRulesComplete()
1161 {
1163 MetaPropertyHasChanged("IsSelfValid");
1164 MetaPropertyHasChanged("IsValid");
1165 MetaPropertyHasChanged("IsSavable");
1166 }
1167
1178 protected virtual void AddBusinessRules()
1179 {
1181 }
1182
1202 [Browsable(false)]
1203 [Display(AutoGenerateField = false)]
1204 [ScaffoldColumn(false)]
1205 public virtual bool IsValid
1206 {
1207 get { return IsSelfValid && (_fieldManager == null || FieldManager.IsValid()); }
1208 }
1209
1225 [Browsable(false)]
1226 [Display(AutoGenerateField = false)]
1227 [ScaffoldColumn(false)]
1228 public virtual bool IsSelfValid
1229 {
1230 get { return BusinessRules.IsValid; }
1231 }
1232
1237 [Browsable(false)]
1238 [Display(AutoGenerateField = false)]
1239 [ScaffoldColumn(false)]
1240 [System.ComponentModel.DataAnnotations.Schema.NotMapped]
1241 [EditorBrowsable(EditorBrowsableState.Advanced)]
1242 public virtual Rules.BrokenRulesCollection BrokenRulesCollection
1243 {
1244 get { return BusinessRules.GetBrokenRules(); }
1245 }
1246
1247#endregion
1248
1249#region Data Access
1250
1256 [EditorBrowsable(EditorBrowsableState.Advanced)]
1258 { }
1259
1265 [EditorBrowsable(EditorBrowsableState.Advanced)]
1267 { }
1268
1275 [EditorBrowsable(EditorBrowsableState.Advanced)]
1276 protected virtual void DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)
1277 { }
1278
1288 protected virtual void Child_Create()
1289 {
1291 }
1292
1298 [EditorBrowsable(EditorBrowsableState.Advanced)]
1300 { }
1301
1307 [EditorBrowsable(EditorBrowsableState.Advanced)]
1309 { }
1310
1317 [EditorBrowsable(EditorBrowsableState.Advanced)]
1318 protected virtual void Child_OnDataPortalException(DataPortalEventArgs e, Exception ex)
1319 { }
1320
1321#endregion
1322
1323 #region IDataErrorInfo
1324
1325 string IDataErrorInfo.Error
1326 {
1327 get
1328 {
1329 if (!IsSelfValid)
1331 Csla.Rules.RuleSeverity.Error);
1332 else
1333 return String.Empty;
1334 }
1335 }
1336
1337 IEnumerable INotifyDataErrorInfo.GetErrors(string propertyName)
1338 {
1339 return BusinessRules.GetBrokenRules().Select(r => r.Description);
1340 }
1341
1342 bool INotifyDataErrorInfo.HasErrors => !IsSelfValid;
1343
1344 string IDataErrorInfo.this[string columnName]
1345 {
1346 get
1347 {
1348 string result = string.Empty;
1349 if (!IsSelfValid)
1350 {
1351 Rules.BrokenRule rule =
1353 if (rule != null)
1354 result = rule.Description;
1355 }
1356 return result;
1357 }
1358 }
1359
1360 [NonSerialized]
1361 [NotUndoable]
1362 private EventHandler<DataErrorsChangedEventArgs> _errorsChanged;
1363
1364 event EventHandler<DataErrorsChangedEventArgs> INotifyDataErrorInfo.ErrorsChanged
1365 {
1366 add
1367 {
1368 _errorsChanged = (EventHandler<DataErrorsChangedEventArgs>)
1369 System.Delegate.Combine(_errorsChanged, value);
1370 }
1371 remove
1372 {
1373 _errorsChanged = (EventHandler<DataErrorsChangedEventArgs>)
1374 System.Delegate.Remove(_errorsChanged, value);
1375 }
1376 }
1377
1382 protected virtual void OnErrorsChanged(string propertyName)
1383 {
1384 _errorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
1385 }
1386
1397 [EditorBrowsable(EditorBrowsableState.Advanced)]
1398 protected override void OnPropertyChanged(IPropertyInfo propertyInfo)
1399 {
1400 base.OnPropertyChanged(propertyInfo);
1401 OnErrorsChanged(propertyInfo.Name);
1402 }
1403
1404 #endregion
1405
1406 #region Serialization Notification
1407
1409 {
1410 OnDeserializedHandler(new System.Runtime.Serialization.StreamingContext());
1411 }
1412
1413 [System.Runtime.Serialization.OnDeserialized]
1414 private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
1415 {
1416 BusinessRules.SetTarget(this);
1417 if (_fieldManager != null)
1418 FieldManager.SetPropertyList(this.GetType());
1419 InitializeBusinessRules();
1420 FieldDataDeserialized();
1421
1422 OnDeserialized(context);
1423 }
1424
1430 [EditorBrowsable(EditorBrowsableState.Advanced)]
1431 protected virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
1432 { }
1433
1434#endregion
1435
1436#region Bubbling event Hooks
1437
1442 [EditorBrowsable(EditorBrowsableState.Never)]
1443 protected void AddEventHooks(IBusinessObject child)
1444 {
1445 OnAddEventHooks(child);
1446 }
1447
1452 [EditorBrowsable(EditorBrowsableState.Never)]
1453 protected virtual void OnAddEventHooks(IBusinessObject child)
1454 {
1455 INotifyBusy busy = child as INotifyBusy;
1456 if (busy != null)
1457 busy.BusyChanged += Child_BusyChanged;
1458
1460 if (unhandled != null)
1461 unhandled.UnhandledAsyncException += Child_UnhandledAsyncException;
1462
1463 INotifyPropertyChanged pc = child as INotifyPropertyChanged;
1464 if (pc != null)
1465 pc.PropertyChanged += Child_PropertyChanged;
1466
1467 IBindingList bl = child as IBindingList;
1468 if (bl != null)
1469 bl.ListChanged += Child_ListChanged;
1470
1471 INotifyCollectionChanged ncc = child as INotifyCollectionChanged;
1472 if (ncc != null)
1473 ncc.CollectionChanged += Child_CollectionChanged;
1474
1476 if (cc != null)
1477 cc.ChildChanged += Child_Changed;
1478 }
1479
1484 [EditorBrowsable(EditorBrowsableState.Never)]
1485 protected void RemoveEventHooks(IBusinessObject child)
1486 {
1487 OnRemoveEventHooks(child);
1488 }
1489
1494 [EditorBrowsable(EditorBrowsableState.Never)]
1495 protected virtual void OnRemoveEventHooks(IBusinessObject child)
1496 {
1497 INotifyBusy busy = child as INotifyBusy;
1498 if (busy != null)
1499 busy.BusyChanged -= Child_BusyChanged;
1500
1502 if (unhandled != null)
1503 unhandled.UnhandledAsyncException -= Child_UnhandledAsyncException;
1504
1505 INotifyPropertyChanged pc = child as INotifyPropertyChanged;
1506 if (pc != null)
1507 pc.PropertyChanged -= Child_PropertyChanged;
1508
1509 IBindingList bl = child as IBindingList;
1510 if (bl != null)
1511 bl.ListChanged -= Child_ListChanged;
1512
1513 INotifyCollectionChanged ncc = child as INotifyCollectionChanged;
1514 if (ncc != null)
1515 ncc.CollectionChanged -= Child_CollectionChanged;
1516
1518 if (cc != null)
1519 cc.ChildChanged -= Child_Changed;
1520 }
1521
1522#endregion
1523
1524#region Busy / Unhandled exception bubbling
1525
1526 private void Child_UnhandledAsyncException(object sender, ErrorEventArgs e)
1527 {
1529 }
1530
1531 private void Child_BusyChanged(object sender, BusyChangedEventArgs e)
1532 {
1533 OnBusyChanged(e);
1534 }
1535
1536#endregion
1537
1538#region IEditableBusinessObject Members
1539
1540 int IEditableBusinessObject.EditLevelAdded
1541 {
1542 get
1543 {
1544 return this.EditLevelAdded;
1545 }
1546 set
1547 {
1548 this.EditLevelAdded = value;
1549 }
1550 }
1551
1552 void IEditableBusinessObject.DeleteChild()
1553 {
1554 this.DeleteChild();
1555 }
1556
1557 void IEditableBusinessObject.SetParent(IParent parent)
1558 {
1559 this.SetParent(parent);
1560 }
1561
1562#endregion
1563
1564#region Register Methods
1565
1579 protected static Csla.Core.IMemberInfo RegisterMethod(Type objectType, IMemberInfo info)
1580 {
1581 var reflected = objectType.GetMethod(info.Name);
1582 if (reflected == null)
1583 throw new ArgumentException(string.Format(Resources.NoSuchMethod, info.Name), "info");
1584 return info;
1585 }
1586
1600 protected static MethodInfo RegisterMethod(Type objectType, string methodName)
1601 {
1602 var info = new MethodInfo(methodName);
1603 RegisterMethod(objectType, info);
1604 return info;
1605 }
1606
1607#endregion
1608
1609#region Register Properties
1610
1627 protected static PropertyInfo<P> RegisterProperty<P>(Type objectType, PropertyInfo<P> info)
1628 {
1629 return Core.FieldManager.PropertyInfoManager.RegisterProperty<P>(objectType, info);
1630 }
1631
1632#endregion
1633
1634#region Get Properties
1635
1654 protected P GetProperty<P>(string propertyName, P field, P defaultValue)
1655 {
1656 return GetProperty<P>(propertyName, field, defaultValue, Security.NoAccessBehavior.SuppressException);
1657 }
1658
1675 protected P GetProperty<P>(string propertyName, P field, P defaultValue, Security.NoAccessBehavior noAccess)
1676 {
1677#region Check to see if the property is marked with RelationshipTypes.PrivateField
1678
1679 var propertyInfo = FieldManager.GetRegisteredProperty(propertyName);
1680
1681 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) != RelationshipTypes.PrivateField)
1682 throw new InvalidOperationException(Resources.PrivateFieldException);
1683
1684#endregion
1685
1686 if (_bypassPropertyChecks || CanReadProperty(propertyInfo, noAccess == Security.NoAccessBehavior.ThrowException))
1687 return field;
1688
1689 return defaultValue;
1690 }
1691
1707 protected P GetProperty<P>(PropertyInfo<P> propertyInfo, P field)
1708 {
1709 return GetProperty<P>(propertyInfo.Name, field, propertyInfo.DefaultValue, Security.NoAccessBehavior.SuppressException);
1710 }
1711
1728 protected P GetProperty<P>(PropertyInfo<P> propertyInfo, P field, P defaultValue, Security.NoAccessBehavior noAccess)
1729 {
1730 return GetProperty<P>(propertyInfo.Name, field, defaultValue, noAccess);
1731 }
1732
1752 protected P GetPropertyConvert<F, P>(PropertyInfo<F> propertyInfo, F field)
1753 {
1754 return Utilities.CoerceValue<P>(typeof(F), null, GetProperty<F>(propertyInfo.Name, field, propertyInfo.DefaultValue, Security.NoAccessBehavior.SuppressException));
1755 }
1756
1779 protected P GetPropertyConvert<F, P>(PropertyInfo<F> propertyInfo, F field, Security.NoAccessBehavior noAccess)
1780 {
1781 return Utilities.CoerceValue<P>(typeof(F), null, GetProperty<F>(propertyInfo.Name, field, propertyInfo.DefaultValue, noAccess));
1782 }
1783
1798 protected P GetProperty<P>(PropertyInfo<P> propertyInfo)
1799 {
1800 return GetProperty<P>(propertyInfo, Security.NoAccessBehavior.SuppressException);
1801 }
1802
1822 {
1823 return Utilities.CoerceValue<P>(typeof(F), null, GetProperty<F>(propertyInfo, Security.NoAccessBehavior.SuppressException));
1824 }
1825
1847 protected P GetPropertyConvert<F, P>(PropertyInfo<F> propertyInfo, Security.NoAccessBehavior noAccess)
1848 {
1849 return Utilities.CoerceValue<P>(typeof(F), null, GetProperty<F>(propertyInfo, noAccess));
1850 }
1851
1869 protected P GetProperty<P>(PropertyInfo<P> propertyInfo, Security.NoAccessBehavior noAccess)
1870 {
1871 if (((propertyInfo.RelationshipType & RelationshipTypes.LazyLoad) == RelationshipTypes.LazyLoad) && !FieldManager.FieldExists(propertyInfo))
1872 {
1873 if (PropertyIsLoading(propertyInfo))
1874 return propertyInfo.DefaultValue;
1875 throw new InvalidOperationException(Resources.PropertyGetNotAllowed);
1876 }
1877
1878 P result = default;
1879 if (_bypassPropertyChecks || CanReadProperty(propertyInfo, noAccess == Csla.Security.NoAccessBehavior.ThrowException))
1880 result = ReadProperty<P>(propertyInfo);
1881 else
1882 result = propertyInfo.DefaultValue;
1883 return result;
1884 }
1885
1896 protected object GetProperty(IPropertyInfo propertyInfo)
1897 {
1898 object result;
1899 if (_bypassPropertyChecks || CanReadProperty(propertyInfo, false))
1900 {
1901 // call ReadProperty (may be overloaded in actual class)
1902 result = ReadProperty(propertyInfo);
1903 }
1904 else
1905 {
1906 result = propertyInfo.DefaultValue;
1907 }
1908 return result;
1909 }
1910
1925 protected P GetProperty<P>(IPropertyInfo propertyInfo)
1926 {
1927 return (P)GetProperty(propertyInfo);
1928 }
1929
1943 protected P LazyGetProperty<P>(PropertyInfo<P> property, Func<P> valueGenerator)
1944 {
1945 if (!(FieldManager.FieldExists(property)))
1946 {
1947 var result = valueGenerator();
1948 LoadProperty(property, result);
1949 }
1950 return GetProperty<P>(property);
1951 }
1952
1959 protected bool PropertyIsLoading(IPropertyInfo propertyInfo)
1960 {
1961 return LoadManager.IsLoadingProperty(propertyInfo);
1962 }
1963
1984 protected P LazyGetPropertyAsync<P>(PropertyInfo<P> property, Task<P> factory)
1985 {
1986 if (!(FieldManager.FieldExists(property)) && !PropertyIsLoading(property))
1987 {
1988 LoadPropertyAsync(property, factory);
1989 }
1990 return GetProperty<P>(property);
1991 }
1992
1993 object IManageProperties.LazyGetProperty<P>(PropertyInfo<P> propertyInfo, Func<P> valueGenerator)
1994 {
1995 return LazyGetProperty(propertyInfo, valueGenerator);
1996 }
1997
1998 object IManageProperties.LazyGetPropertyAsync<P>(PropertyInfo<P> propertyInfo, Task<P> factory)
1999 {
2000 return LazyGetPropertyAsync(propertyInfo, factory);
2001 }
2002
2003#endregion
2004
2005#region Read Properties
2006
2021 {
2022 return Utilities.CoerceValue<P>(typeof(F), null, ReadProperty<F>(propertyInfo));
2023 }
2024
2033 protected P ReadProperty<P>(PropertyInfo<P> propertyInfo)
2034 {
2035 if (((propertyInfo.RelationshipType & RelationshipTypes.LazyLoad) == RelationshipTypes.LazyLoad) && !FieldManager.FieldExists(propertyInfo))
2036 {
2037 if (PropertyIsLoading(propertyInfo))
2038 return default;
2039 throw new InvalidOperationException(Resources.PropertyGetNotAllowed);
2040 }
2041
2042 P result = default;
2043 FieldManager.IFieldData data = FieldManager.GetFieldData(propertyInfo);
2044 if (data != null)
2045 {
2046 FieldManager.IFieldData<P> fd = data as FieldManager.IFieldData<P>;
2047 if (fd != null)
2048 result = fd.Value;
2049 else
2050 result = (P)data.Value;
2051 }
2052 else
2053 {
2054 result = propertyInfo.DefaultValue;
2055 FieldManager.LoadFieldData<P>(propertyInfo, result);
2056 }
2057 return result;
2058 }
2059
2065 protected virtual object ReadProperty(IPropertyInfo propertyInfo)
2066 {
2067 if (((propertyInfo.RelationshipType & RelationshipTypes.LazyLoad) == RelationshipTypes.LazyLoad) && !FieldManager.FieldExists(propertyInfo))
2068 throw new InvalidOperationException(Resources.PropertyGetNotAllowed);
2069
2070 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
2071 {
2072 using (BypassPropertyChecks)
2073 {
2074 return MethodCaller.CallPropertyGetter(this, propertyInfo.Name);
2075 }
2076 }
2077
2078 object result = null;
2079 var info = FieldManager.GetFieldData(propertyInfo);
2080 if (info != null)
2081 {
2082 result = info.Value;
2083 }
2084 else
2085 {
2086 result = propertyInfo.DefaultValue;
2087 FieldManager.LoadFieldData(propertyInfo, result);
2088 }
2089
2090 return result;
2091 }
2092
2102 protected P LazyReadProperty<P>(PropertyInfo<P> property, Func<P> valueGenerator)
2103 {
2104 if (!(FieldManager.FieldExists(property)))
2105 {
2106 var result = valueGenerator();
2107 LoadProperty(property, result);
2108 }
2109 return ReadProperty<P>(property);
2110 }
2111
2121 protected P LazyReadPropertyAsync<P>(PropertyInfo<P> property, Task<P> factory)
2122 {
2123 if (!(FieldManager.FieldExists(property)) && !PropertyIsLoading(property))
2124 {
2125 LoadPropertyAsync(property, factory);
2126 }
2127 return ReadProperty<P>(property);
2128 }
2129
2130 P IManageProperties.LazyReadProperty<P>(PropertyInfo<P> propertyInfo, Func<P> valueGenerator)
2131 {
2132 return LazyReadProperty(propertyInfo, valueGenerator);
2133 }
2134
2135 P IManageProperties.LazyReadPropertyAsync<P>(PropertyInfo<P> propertyInfo, Task<P> factory)
2136 {
2137 return LazyReadPropertyAsync(propertyInfo, factory);
2138 }
2139
2140#endregion
2141
2142#region Set Properties
2143
2159 protected void SetProperty<P>(PropertyInfo<P> propertyInfo, ref P field, P newValue)
2160 {
2161 SetProperty<P>(propertyInfo.Name, ref field, newValue, Security.NoAccessBehavior.ThrowException);
2162 }
2163
2179 protected void SetProperty<P>(string propertyName, ref P field, P newValue)
2180 {
2181 SetProperty<P>(propertyName, ref field, newValue, Security.NoAccessBehavior.ThrowException);
2182 }
2183
2205 protected void SetPropertyConvert<P, V>(PropertyInfo<P> propertyInfo, ref P field, V newValue)
2206 {
2207 SetPropertyConvert<P, V>(propertyInfo, ref field, newValue, Security.NoAccessBehavior.ThrowException);
2208 }
2209
2234 protected void SetPropertyConvert<P, V>(PropertyInfo<P> propertyInfo, ref P field, V newValue, Security.NoAccessBehavior noAccess)
2235 {
2236 SetPropertyConvert<P, V>(propertyInfo.Name, ref field, newValue, noAccess);
2237 }
2238
2253 protected void SetProperty<P>(string propertyName, ref P field, P newValue, Security.NoAccessBehavior noAccess)
2254 {
2255 try
2256 {
2257#region Check to see if the property is marked with RelationshipTypes.PrivateField
2258
2259 var propertyInfo = FieldManager.GetRegisteredProperty(propertyName);
2260
2261 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) != RelationshipTypes.PrivateField)
2262 throw new InvalidOperationException(Resources.PrivateFieldException);
2263
2264#endregion
2265
2266 if (_bypassPropertyChecks || CanWriteProperty(propertyInfo, noAccess == Security.NoAccessBehavior.ThrowException))
2267 {
2268 bool doChange = false;
2269 if (field == null)
2270 {
2271 if (newValue != null)
2272 doChange = true;
2273 }
2274 else
2275 {
2276 if (typeof(P) == typeof(string) && newValue == null)
2277 newValue = Utilities.CoerceValue<P>(typeof(string), field, string.Empty);
2278 if (!field.Equals(newValue))
2279 doChange = true;
2280 }
2281 if (doChange)
2282 {
2283 if (!_bypassPropertyChecks) OnPropertyChanging(propertyName);
2284 field = newValue;
2285 if (!_bypassPropertyChecks) PropertyHasChanged(propertyName);
2286 }
2287 }
2288 }
2289 catch (System.Security.SecurityException ex)
2290 {
2291 throw new Csla.Security.SecurityException(ex.Message);
2292 }
2294 {
2295 throw;
2296 }
2297 catch (Exception ex)
2298 {
2299 throw new PropertyLoadException(
2300 string.Format(Resources.PropertyLoadException, propertyName, ex.Message, ex.Message), ex);
2301 }
2302 }
2303
2328 protected void SetPropertyConvert<P, V>(string propertyName, ref P field, V newValue, Security.NoAccessBehavior noAccess)
2329 {
2330 try
2331 {
2332#region Check to see if the property is marked with RelationshipTypes.PrivateField
2333
2334 var propertyInfo = FieldManager.GetRegisteredProperty(propertyName);
2335
2336 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) != RelationshipTypes.PrivateField)
2337 throw new InvalidOperationException(Resources.PrivateFieldException);
2338
2339#endregion
2340
2341 if (_bypassPropertyChecks || CanWriteProperty(propertyInfo, noAccess == Security.NoAccessBehavior.ThrowException))
2342 {
2343 bool doChange = false;
2344 if (field == null)
2345 {
2346 if (newValue != null)
2347 doChange = true;
2348 }
2349 else
2350 {
2351 if (typeof(V) == typeof(string) && newValue == null)
2352 newValue = Utilities.CoerceValue<V>(typeof(string), null, string.Empty);
2353 if (!field.Equals(newValue))
2354 doChange = true;
2355 }
2356 if (doChange)
2357 {
2358 if (!_bypassPropertyChecks) OnPropertyChanging(propertyName);
2359 field = Utilities.CoerceValue<P>(typeof(V), field, newValue);
2360 if (!_bypassPropertyChecks) PropertyHasChanged(propertyName);
2361 }
2362 }
2363 }
2364 catch (System.Security.SecurityException ex)
2365 {
2366 throw new Csla.Security.SecurityException(ex.Message);
2367 }
2369 {
2370 throw;
2371 }
2372 catch (Exception ex)
2373 {
2374 throw new PropertyLoadException(
2375 string.Format(Properties.Resources.PropertyLoadException, propertyName, ex.Message), ex);
2376 }
2377 }
2378
2393 protected void SetProperty<P>(PropertyInfo<P> propertyInfo, P newValue)
2394 {
2395 SetProperty<P>(propertyInfo, newValue, Security.NoAccessBehavior.ThrowException);
2396 }
2397
2411 protected void SetPropertyConvert<P, F>(PropertyInfo<P> propertyInfo, F newValue)
2412 {
2413 SetPropertyConvert<P, F>(propertyInfo, newValue, Security.NoAccessBehavior.ThrowException);
2414 }
2415
2428 protected void SetPropertyConvert<P, F>(PropertyInfo<P> propertyInfo, F newValue, Security.NoAccessBehavior noAccess)
2429 {
2430 try
2431 {
2432 if (_bypassPropertyChecks || CanWriteProperty(propertyInfo, noAccess == Security.NoAccessBehavior.ThrowException))
2433 {
2434 P oldValue = default(P);
2435 var fieldData = FieldManager.GetFieldData(propertyInfo);
2436 if (fieldData == null)
2437 {
2438 oldValue = propertyInfo.DefaultValue;
2439 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
2440 }
2441 else
2442 {
2443 var fd = fieldData as FieldManager.IFieldData<P>;
2444 if (fd != null)
2445 oldValue = fd.Value;
2446 else
2447 oldValue = (P)fieldData.Value;
2448 }
2449 if (typeof(F) == typeof(string) && newValue == null)
2450 newValue = Utilities.CoerceValue<F>(typeof(string), null, string.Empty);
2451 LoadPropertyValue<P>(propertyInfo, oldValue, Utilities.CoerceValue<P>(typeof(F), oldValue, newValue), !_bypassPropertyChecks);
2452 }
2453 }
2454 catch (System.Security.SecurityException ex)
2455 {
2456 throw new Csla.Security.SecurityException(ex.Message);
2457 }
2459 {
2460 throw;
2461 }
2462 catch (Exception ex)
2463 {
2464 throw new PropertyLoadException(
2465 string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2466 }
2467 }
2468
2484 protected void SetProperty<P>(PropertyInfo<P> propertyInfo, P newValue, Security.NoAccessBehavior noAccess)
2485 {
2486 if (_bypassPropertyChecks || CanWriteProperty(propertyInfo, noAccess == Security.NoAccessBehavior.ThrowException))
2487 {
2488 try
2489 {
2490 P oldValue = default(P);
2491 var fieldData = FieldManager.GetFieldData(propertyInfo);
2492 if (fieldData == null)
2493 {
2494 oldValue = propertyInfo.DefaultValue;
2495 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
2496 }
2497 else
2498 {
2499 var fd = fieldData as FieldManager.IFieldData<P>;
2500 if (fd != null)
2501 oldValue = fd.Value;
2502 else
2503 oldValue = (P)fieldData.Value;
2504 }
2505 if (typeof(P) == typeof(string) && newValue == null)
2506 newValue = Utilities.CoerceValue<P>(typeof(string), null, string.Empty);
2507 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, !_bypassPropertyChecks);
2508 }
2509 catch (Exception ex)
2510 {
2511 throw new PropertyLoadException(
2512 string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2513 }
2514 }
2515 }
2516
2530 protected void SetProperty(IPropertyInfo propertyInfo, object newValue)
2531 {
2532 try
2533 {
2534 if (_bypassPropertyChecks || CanWriteProperty(propertyInfo, true))
2535 {
2536 if (!_bypassPropertyChecks) OnPropertyChanging(propertyInfo);
2537 FieldManager.SetFieldData(propertyInfo, newValue);
2538 if (!_bypassPropertyChecks) PropertyHasChanged(propertyInfo);
2539 }
2540 }
2541 catch (System.Security.SecurityException ex)
2542 {
2543 throw new Csla.Security.SecurityException(ex.Message);
2544 }
2546 {
2547 throw;
2548 }
2549 catch (Exception ex)
2550 {
2551 throw new PropertyLoadException(
2552 string.Format(Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2553 }
2554 }
2555
2572 protected void SetProperty<P>(IPropertyInfo propertyInfo, P newValue)
2573 {
2574 SetProperty(propertyInfo, (object)newValue);
2575 }
2576
2577#endregion
2578
2579#region Load Properties
2580
2595 protected void LoadPropertyConvert<P, F>(PropertyInfo<P> propertyInfo, F newValue)
2596 {
2597 try
2598 {
2599 P oldValue = default(P);
2600 var fieldData = FieldManager.GetFieldData(propertyInfo);
2601 if (fieldData == null)
2602 {
2603 oldValue = propertyInfo.DefaultValue;
2604 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
2605 }
2606 else
2607 {
2608 var fd = fieldData as FieldManager.IFieldData<P>;
2609 if (fd != null)
2610 oldValue = fd.Value;
2611 else
2612 oldValue = (P)fieldData.Value;
2613 }
2614 LoadPropertyValue<P>(propertyInfo, oldValue, Utilities.CoerceValue<P>(typeof(F), oldValue, newValue), false);
2615 }
2616 catch (Exception ex)
2617 {
2618 throw new PropertyLoadException(
2619 string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2620 }
2621 }
2622
2623 void Core.IManageProperties.LoadProperty<P>(PropertyInfo<P> propertyInfo, P newValue)
2624 {
2625 LoadProperty<P>(propertyInfo, newValue);
2626 }
2627
2628 bool Core.IManageProperties.FieldExists(Core.IPropertyInfo property)
2629 {
2630 return FieldManager.FieldExists(property);
2631 }
2632
2650 protected void LoadProperty<P>(PropertyInfo<P> propertyInfo, P newValue)
2651 {
2652 try
2653 {
2654 P oldValue = default(P);
2655 var fieldData = FieldManager.GetFieldData(propertyInfo);
2656 if (fieldData == null)
2657 {
2658 oldValue = propertyInfo.DefaultValue;
2659 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
2660 }
2661 else
2662 {
2663 var fd = fieldData as FieldManager.IFieldData<P>;
2664 if (fd != null)
2665 oldValue = fd.Value;
2666 else
2667 oldValue = (P)fieldData.Value;
2668 }
2669 LoadPropertyValue<P>(propertyInfo, oldValue, newValue, false);
2670 }
2671 catch (Exception ex)
2672 {
2673 throw new PropertyLoadException(
2674 string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2675 }
2676 }
2677
2695 protected bool LoadPropertyMarkDirty<P>(PropertyInfo<P> propertyInfo, P newValue)
2696 {
2697 try
2698 {
2699 P oldValue = default(P);
2700 var fieldData = FieldManager.GetFieldData(propertyInfo);
2701 if (fieldData == null)
2702 {
2703 oldValue = propertyInfo.DefaultValue;
2704 fieldData = FieldManager.LoadFieldData<P>(propertyInfo, oldValue);
2705 }
2706 else
2707 {
2708 var fd = fieldData as FieldManager.IFieldData<P>;
2709 if (fd != null)
2710 oldValue = fd.Value;
2711 else
2712 oldValue = (P)fieldData.Value;
2713 }
2714
2715 var valuesDiffer = ValuesDiffer(propertyInfo, newValue, oldValue);
2716 if (valuesDiffer)
2717 {
2718
2719 IBusinessObject old = oldValue as IBusinessObject;
2720 if (old != null)
2721 RemoveEventHooks(old);
2722 IBusinessObject @new = newValue as IBusinessObject;
2723 if (@new != null)
2724 AddEventHooks(@new);
2725
2726 if (typeof(IEditableBusinessObject).IsAssignableFrom(propertyInfo.Type))
2727 {
2728 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2729 ResetChildEditLevel(newValue);
2730 }
2731 else if (typeof(IEditableCollection).IsAssignableFrom(propertyInfo.Type))
2732 {
2733 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2734 ResetChildEditLevel(newValue);
2735 }
2736 else
2737 {
2738 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2739 }
2740 }
2741 return valuesDiffer;
2742 }
2743 catch (Exception ex)
2744 {
2745 throw new PropertyLoadException(string.Format(Properties.Resources.PropertyLoadException, propertyInfo.Name, ex.Message), ex);
2746 }
2747 }
2748
2757 private static bool ValuesDiffer<P>(PropertyInfo<P> propertyInfo, P newValue, P oldValue)
2758 {
2759 var valuesDiffer = false;
2760 if (oldValue == null)
2761 valuesDiffer = newValue != null;
2762 else
2763 {
2764 // use reference equals for objects that inherit from CSLA base class
2765 if (typeof (IBusinessObject).IsAssignableFrom(propertyInfo.Type))
2766 {
2767 valuesDiffer = !(ReferenceEquals(oldValue, newValue));
2768 }
2769 else
2770 {
2771 valuesDiffer = !(oldValue.Equals(newValue));
2772 }
2773 }
2774 return valuesDiffer;
2775 }
2776
2777 private void LoadPropertyValue<P>(PropertyInfo<P> propertyInfo, P oldValue, P newValue, bool markDirty)
2778 {
2779 var valuesDiffer = ValuesDiffer(propertyInfo, newValue, oldValue);
2780
2781 if (valuesDiffer)
2782 {
2783
2784 IBusinessObject old = oldValue as IBusinessObject;
2785 if (old != null)
2786 RemoveEventHooks(old);
2787 IBusinessObject @new = newValue as IBusinessObject;
2788 if (@new != null)
2789 AddEventHooks(@new);
2790
2791
2792 if (typeof(IEditableBusinessObject).IsAssignableFrom(propertyInfo.Type))
2793 {
2794 if (markDirty)
2795 {
2796 OnPropertyChanging(propertyInfo);
2797 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2798 PropertyHasChanged(propertyInfo);
2799 }
2800 else
2801 {
2802 FieldManager.LoadFieldData<P>(propertyInfo, newValue);
2803 }
2804 ResetChildEditLevel(newValue);
2805 }
2806 else if (typeof(IEditableCollection).IsAssignableFrom(propertyInfo.Type))
2807 {
2808 if (markDirty)
2809 {
2810 OnPropertyChanging(propertyInfo);
2811 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2812 PropertyHasChanged(propertyInfo);
2813 }
2814 else
2815 {
2816 FieldManager.LoadFieldData<P>(propertyInfo, newValue);
2817 }
2818 ResetChildEditLevel(newValue);
2819 }
2820 else
2821 {
2822 if (markDirty)
2823 {
2824 OnPropertyChanging(propertyInfo);
2825 FieldManager.SetFieldData<P>(propertyInfo, newValue);
2826 PropertyHasChanged(propertyInfo);
2827 }
2828 else
2829 {
2830 FieldManager.LoadFieldData<P>(propertyInfo, newValue);
2831 }
2832 }
2833 }
2834 }
2835
2850 protected virtual bool LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
2851 {
2852 // private field
2853 if ((propertyInfo.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
2854 {
2855 LoadProperty(propertyInfo, newValue);
2856 return false;
2857 }
2858
2859#if IOS
2860 //manually call LoadProperty<T> if the type is nullable otherwise JIT error will occur
2861 if (propertyInfo.Type == typeof(int?))
2862 {
2863 return LoadPropertyMarkDirty((PropertyInfo<int?>)propertyInfo, (int?)newValue);
2864 }
2865 else if (propertyInfo.Type == typeof(bool?))
2866 {
2867 return LoadPropertyMarkDirty((PropertyInfo<bool?>)propertyInfo, (bool?)newValue);
2868 }
2869 else if (propertyInfo.Type == typeof(DateTime?))
2870 {
2871 return LoadPropertyMarkDirty((PropertyInfo<DateTime?>)propertyInfo, (DateTime?)newValue);
2872 }
2873 else if (propertyInfo.Type == typeof(decimal?))
2874 {
2875 return LoadPropertyMarkDirty((PropertyInfo<decimal?>)propertyInfo, (decimal?)newValue);
2876 }
2877 else if (propertyInfo.Type == typeof(double?))
2878 {
2879 return LoadPropertyMarkDirty((PropertyInfo<double?>)propertyInfo, (double?)newValue);
2880 }
2881 else if (propertyInfo.Type == typeof(long?))
2882 {
2883 return LoadPropertyMarkDirty((PropertyInfo<long?>)propertyInfo, (long?)newValue);
2884 }
2885 else if (propertyInfo.Type == typeof(byte?))
2886 {
2887 return LoadPropertyMarkDirty((PropertyInfo<byte?>)propertyInfo, (byte?)newValue);
2888 }
2889 else if (propertyInfo.Type == typeof(char?))
2890 {
2891 return LoadPropertyMarkDirty((PropertyInfo<char?>)propertyInfo, (char?)newValue);
2892 }
2893 else if (propertyInfo.Type == typeof(short?))
2894 {
2895 return LoadPropertyMarkDirty((PropertyInfo<short?>)propertyInfo, (short?)newValue);
2896 }
2897 else if (propertyInfo.Type == typeof(uint?))
2898 {
2899 return LoadPropertyMarkDirty((PropertyInfo<uint?>)propertyInfo, (uint?)newValue);
2900 }
2901 else if (propertyInfo.Type == typeof(ulong?))
2902 {
2903 return LoadPropertyMarkDirty((PropertyInfo<ulong?>)propertyInfo, (ulong?)newValue);
2904 }
2905 else if (propertyInfo.Type == typeof(ushort?))
2906 {
2907 return LoadPropertyMarkDirty((PropertyInfo<ushort?>)propertyInfo, (ushort?)newValue);
2908 }
2909 else
2910 {
2911 return (bool)LoadPropertyByReflection("LoadPropertyMarkDirty", propertyInfo, newValue);
2912 }
2913#else
2914 return (bool)LoadPropertyByReflection("LoadPropertyMarkDirty", propertyInfo, newValue);
2915#endif
2916 }
2917
2918
2933 protected virtual void LoadProperty(IPropertyInfo propertyInfo, object newValue)
2934 {
2935#if IOS
2936 //manually call LoadProperty<T> if the type is nullable otherwise JIT error will occur
2937 if (propertyInfo.Type == typeof(int?))
2938 {
2939 LoadProperty((PropertyInfo<int?>)propertyInfo, (int?)newValue);
2940 }
2941 else if (propertyInfo.Type == typeof(bool?))
2942 {
2943 LoadProperty((PropertyInfo<bool?>)propertyInfo, (bool?)newValue);
2944 }
2945 else if (propertyInfo.Type == typeof(DateTime?))
2946 {
2947 LoadProperty((PropertyInfo<DateTime?>)propertyInfo, (DateTime?)newValue);
2948 }
2949 else if (propertyInfo.Type == typeof(decimal?))
2950 {
2951 LoadProperty((PropertyInfo<decimal?>)propertyInfo, (decimal?)newValue);
2952 }
2953 else if (propertyInfo.Type == typeof(double?))
2954 {
2955 LoadProperty((PropertyInfo<double?>)propertyInfo, (double?)newValue);
2956 }
2957 else if (propertyInfo.Type == typeof(long?))
2958 {
2959 LoadProperty((PropertyInfo<long?>)propertyInfo, (long?)newValue);
2960 }
2961 else if (propertyInfo.Type == typeof(byte?))
2962 {
2963 LoadProperty((PropertyInfo<byte?>)propertyInfo, (byte?)newValue);
2964 }
2965 else if (propertyInfo.Type == typeof(char?))
2966 {
2967 LoadProperty((PropertyInfo<char?>)propertyInfo, (char?)newValue);
2968 }
2969 else if (propertyInfo.Type == typeof(short?))
2970 {
2971 LoadProperty((PropertyInfo<short?>)propertyInfo, (short?)newValue);
2972 }
2973 else if (propertyInfo.Type == typeof(uint?))
2974 {
2975 LoadProperty((PropertyInfo<uint?>)propertyInfo, (uint?)newValue);
2976 }
2977 else if (propertyInfo.Type == typeof(ulong?))
2978 {
2979 LoadProperty((PropertyInfo<ulong?>)propertyInfo, (ulong?)newValue);
2980 }
2981 else if (propertyInfo.Type == typeof(ushort?))
2982 {
2983 LoadProperty((PropertyInfo<ushort?>)propertyInfo, (ushort?)newValue);
2984 }
2985 else
2986 {
2987 LoadPropertyByReflection("LoadProperty", propertyInfo, newValue);
2988 }
2989#else
2990 LoadPropertyByReflection("LoadProperty", propertyInfo, newValue);
2991#endif
2992 }
2993
3004 private object LoadPropertyByReflection(string loadPropertyMethodName, IPropertyInfo propertyInfo, object newValue)
3005 {
3006 var t = this.GetType();
3007 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
3008 var method = t.GetMethods(flags).FirstOrDefault(c => c.Name == loadPropertyMethodName && c.IsGenericMethod);
3009 var gm = method.MakeGenericMethod(propertyInfo.Type);
3010 var p = new object[] { propertyInfo, newValue };
3011 return gm.Invoke(this, p);
3012 }
3013
3019 private void ResetChildEditLevel(object newValue)
3020 {
3021 IEditableBusinessObject child = newValue as IEditableBusinessObject;
3022 if (child != null)
3023 {
3024 child.SetParent(this);
3025 // set child edit level
3026 UndoableBase.ResetChildEditLevel(child, this.EditLevel, this.BindingEdit);
3027 // reset EditLevelAdded
3028 child.EditLevelAdded = this.EditLevel;
3029 }
3030 else
3031 {
3032 IEditableCollection col = newValue as IEditableCollection;
3033 if (col != null)
3034 {
3035 col.SetParent(this);
3036 IUndoableObject undo = col as IUndoableObject;
3037 if (undo != null)
3038 {
3039 // set child edit level
3040 UndoableBase.ResetChildEditLevel(undo, this.EditLevel, this.BindingEdit);
3041 }
3042 }
3043 }
3044 }
3045
3046 //private AsyncLoadManager
3047 [NonSerialized]
3048 [NotUndoable]
3049 private AsyncLoadManager _loadManager;
3050 internal AsyncLoadManager LoadManager
3051 {
3052 get
3053 {
3054 if (_loadManager == null)
3055 {
3056 _loadManager = new AsyncLoadManager(this, OnPropertyChanged);
3057 _loadManager.BusyChanged += loadManager_BusyChanged;
3058 _loadManager.UnhandledAsyncException += loadManager_UnhandledAsyncException;
3059 }
3060 return _loadManager;
3061 }
3062 }
3063
3064 private void loadManager_UnhandledAsyncException(object sender, ErrorEventArgs e)
3065 {
3067 }
3068
3069 private void loadManager_BusyChanged(object sender, BusyChangedEventArgs e)
3070 {
3071 OnBusyChanged(e);
3072 }
3073
3080 protected void LoadPropertyAsync<R>(PropertyInfo<R> property, Task<R> factory)
3081 {
3082 LoadManager.BeginLoad(new TaskLoader<R>(property, factory));
3083 }
3084
3085#endregion
3086
3087#region IsBusy / IsIdle
3088
3089 [NonSerialized]
3090 [NotUndoable]
3091 private bool _isBusy;
3092
3097 [EditorBrowsable(EditorBrowsableState.Advanced)]
3098 protected void MarkBusy()
3099 {
3100 if (_isBusy)
3101 throw new InvalidOperationException(Resources.BusyObjectsMayNotBeMarkedBusy);
3102
3103 _isBusy = true;
3104 OnBusyChanged(new BusyChangedEventArgs("", true));
3105 }
3106
3111 [EditorBrowsable(EditorBrowsableState.Advanced)]
3112 protected void MarkIdle()
3113 {
3114 _isBusy = false;
3115 OnBusyChanged(new BusyChangedEventArgs("", false));
3116 }
3117
3123 [Browsable(false)]
3124 [Display(AutoGenerateField = false)]
3125 [ScaffoldColumn(false)]
3126 public virtual bool IsBusy
3127 {
3128 get { return IsSelfBusy || (_fieldManager != null && FieldManager.IsBusy()); }
3129 }
3130
3135 [Browsable(false)]
3136 [Display(AutoGenerateField = false)]
3137 [ScaffoldColumn(false)]
3138 public virtual bool IsSelfBusy
3139 {
3140 get { return _isBusy || BusinessRules.RunningAsyncRules || LoadManager.IsLoading; }
3141 }
3142
3143 [NotUndoable]
3144 [NonSerialized]
3145 private BusyChangedEventHandler _busyChanged;
3146
3151 {
3152 add { _busyChanged = (BusyChangedEventHandler)Delegate.Combine(_busyChanged, value); }
3153 remove { _busyChanged = (BusyChangedEventHandler)Delegate.Remove(_busyChanged, value); }
3154 }
3155
3160 protected virtual void OnBusyChanged(BusyChangedEventArgs args)
3161 {
3162 if (_busyChanged != null)
3163 _busyChanged(this, args);
3164 MetaPropertyHasChanged("IsSelfBusy");
3165 MetaPropertyHasChanged("IsBusy");
3166 }
3167
3176 public virtual bool IsPropertyBusy(Csla.Core.IPropertyInfo property)
3177 {
3178 return BusinessRules.GetPropertyBusy(property);
3179 }
3180
3189 public bool IsPropertyBusy(string propertyName)
3190 {
3192 }
3193
3194#endregion
3195
3196#region INotifyUnhandledAsyncException Members
3197
3198 [NotUndoable]
3199 [NonSerialized]
3200 private EventHandler<ErrorEventArgs> _unhandledAsyncException;
3201
3206 public event EventHandler<ErrorEventArgs> UnhandledAsyncException
3207 {
3208 add { _unhandledAsyncException = (EventHandler<ErrorEventArgs>)Delegate.Combine(_unhandledAsyncException, value); }
3209 remove { _unhandledAsyncException = (EventHandler<ErrorEventArgs>)Delegate.Remove(_unhandledAsyncException, value); }
3210 }
3211
3216 [EditorBrowsable(EditorBrowsableState.Advanced)]
3217 protected virtual void OnUnhandledAsyncException(ErrorEventArgs error)
3218 {
3219 if (_unhandledAsyncException != null)
3220 _unhandledAsyncException(this, error);
3221 }
3222
3229 [EditorBrowsable(EditorBrowsableState.Advanced)]
3230 protected void OnUnhandledAsyncException(object originalSender, Exception error)
3231 {
3232 OnUnhandledAsyncException(new ErrorEventArgs(originalSender, error));
3233 }
3234
3235#endregion
3236
3237#region Child Change Notification
3238
3239 [NonSerialized]
3240 [NotUndoable]
3241 private EventHandler<Csla.Core.ChildChangedEventArgs> _childChangedHandlers;
3242
3246 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
3247 "CA1062:ValidateArgumentsOfPublicMethods")]
3248 public event EventHandler<Csla.Core.ChildChangedEventArgs> ChildChanged
3249 {
3250 add
3251 {
3252 _childChangedHandlers = (EventHandler<Csla.Core.ChildChangedEventArgs>)
3253 System.Delegate.Combine(_childChangedHandlers, value);
3254 }
3255 remove
3256 {
3257 _childChangedHandlers = (EventHandler<Csla.Core.ChildChangedEventArgs>)
3258 System.Delegate.Remove(_childChangedHandlers, value);
3259 }
3260 }
3261
3269 [EditorBrowsable(EditorBrowsableState.Advanced)]
3270 protected virtual void OnChildChanged(ChildChangedEventArgs e)
3271 {
3272 if (_childChangedHandlers != null)
3273 _childChangedHandlers.Invoke(this, e);
3274 MetaPropertyHasChanged("IsDirty");
3275 MetaPropertyHasChanged("IsValid");
3276 MetaPropertyHasChanged("IsSavable");
3277 }
3278
3282 private void RaiseChildChanged(ChildChangedEventArgs e)
3283 {
3284 OnChildChanged(e);
3285 }
3286
3290 private void RaiseChildChanged(
3291 object childObject, PropertyChangedEventArgs propertyArgs)
3292 {
3293 ChildChangedEventArgs args = new ChildChangedEventArgs(childObject, propertyArgs);
3294 OnChildChanged(args);
3295 }
3296
3300 private void RaiseChildChanged(
3301 object childObject, PropertyChangedEventArgs propertyArgs, ListChangedEventArgs listArgs)
3302 {
3303 ChildChangedEventArgs args = new ChildChangedEventArgs(childObject, propertyArgs, listArgs);
3304 OnChildChanged(args);
3305 }
3306
3310 private void RaiseChildChanged(
3311 object childObject, PropertyChangedEventArgs propertyArgs, NotifyCollectionChangedEventArgs listArgs)
3312 {
3313 ChildChangedEventArgs args = new ChildChangedEventArgs(childObject, propertyArgs, listArgs);
3314 OnChildChanged(args);
3315 }
3316
3322 private void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
3323 {
3324 // Issue 813
3325 // MetaPropertyHasChanged calls in OnChildChanged we're leading to exponential growth in OnChildChanged calls
3326 // Those notifications are for the UI. Ignore them here
3327 if (!(e is MetaPropertyChangedEventArgs))
3328 {
3329 RaiseChildChanged(sender, e);
3330 }
3331 }
3332
3338 private void Child_ListChanged(object sender, ListChangedEventArgs e)
3339 {
3340 if (e.ListChangedType != ListChangedType.ItemChanged)
3341 RaiseChildChanged(sender, null, e);
3342 }
3343
3349 private void Child_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
3350 {
3351 RaiseChildChanged(sender, null, e);
3352 }
3353
3359 private void Child_Changed(object sender, ChildChangedEventArgs e)
3360 {
3361 RaiseChildChanged(e);
3362 }
3363
3364#endregion
3365
3366#region Field Manager
3367
3368 private FieldManager.FieldDataManager _fieldManager;
3369
3375 {
3376 get
3377 {
3378 if (_fieldManager == null)
3379 {
3380 _fieldManager = new FieldDataManager(ApplicationContext, this.GetType());
3381 UndoableBase.ResetChildEditLevel(_fieldManager, this.EditLevel, this.BindingEdit);
3382 }
3383 return _fieldManager;
3384 }
3385 }
3386
3387 FieldDataManager IUseFieldManager.FieldManager => FieldManager;
3388
3389 private void FieldDataDeserialized()
3390 {
3391 foreach (object item in FieldManager.GetChildren())
3392 {
3393 if (item is IBusinessObject business)
3394 OnAddEventHooks(business);
3395
3396 if (item is IEditableBusinessObject child)
3397 {
3398 child.SetParent(this);
3399 }
3400 if (item is IEditableCollection childCollection)
3401 {
3402 childCollection.SetParent(this);
3403 }
3404 }
3405 }
3406
3407#endregion
3408
3409#region IParent
3410
3417 [EditorBrowsable(EditorBrowsableState.Advanced)]
3418 protected virtual void EditChildComplete(Core.IEditableBusinessObject child)
3419 {
3420 // do nothing, we don't really care
3421 // when a child has its edits applied
3422 }
3423
3424 void IParent.ApplyEditChild(Core.IEditableBusinessObject child)
3425 {
3426 this.EditChildComplete(child);
3427 }
3428
3429 void IParent.RemoveChild(IEditableBusinessObject child)
3430 {
3431 var info = FieldManager.FindProperty(child);
3432 FieldManager.RemoveField(info);
3433 }
3434
3435 IParent Csla.Core.IParent.Parent
3436 {
3437 get { return this.Parent; }
3438 }
3439
3440#endregion
3441
3442#region IDataPortalTarget Members
3443
3444 void Csla.Server.IDataPortalTarget.CheckRules()
3445 {
3447 }
3448
3449 void Csla.Server.IDataPortalTarget.MarkAsChild()
3450 {
3451 this.MarkAsChild();
3452 }
3453
3454 void Csla.Server.IDataPortalTarget.MarkNew()
3455 {
3456 this.MarkNew();
3457 }
3458
3459 void Csla.Server.IDataPortalTarget.MarkOld()
3460 {
3461 this.MarkOld();
3462 }
3463
3464 void Csla.Server.IDataPortalTarget.DataPortal_OnDataPortalInvoke(DataPortalEventArgs e)
3465 {
3467 }
3468
3469 void Csla.Server.IDataPortalTarget.DataPortal_OnDataPortalInvokeComplete(DataPortalEventArgs e)
3470 {
3472 }
3473
3474 void Csla.Server.IDataPortalTarget.DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)
3475 {
3477 }
3478
3479 void Csla.Server.IDataPortalTarget.Child_OnDataPortalInvoke(DataPortalEventArgs e)
3480 {
3482 }
3483
3484 void Csla.Server.IDataPortalTarget.Child_OnDataPortalInvokeComplete(DataPortalEventArgs e)
3485 {
3487 }
3488
3489 void Csla.Server.IDataPortalTarget.Child_OnDataPortalException(DataPortalEventArgs e, Exception ex)
3490 {
3491 this.Child_OnDataPortalException(e, ex);
3492 }
3493
3494#endregion
3495
3496#region IManageProperties Members
3497
3498 bool IManageProperties.HasManagedProperties
3499 {
3500 get { return (_fieldManager != null && _fieldManager.HasFields); }
3501 }
3502
3503 List<IPropertyInfo> IManageProperties.GetManagedProperties()
3504 {
3506 }
3507
3508 object IManageProperties.GetProperty(IPropertyInfo propertyInfo)
3509 {
3510 return GetProperty(propertyInfo);
3511 }
3512
3513 object IManageProperties.ReadProperty(IPropertyInfo propertyInfo)
3514 {
3515 return ReadProperty(propertyInfo);
3516 }
3517
3518 P IManageProperties.ReadProperty<P>(PropertyInfo<P> propertyInfo)
3519 {
3520 return ReadProperty<P>(propertyInfo);
3521 }
3522
3523 void IManageProperties.SetProperty(IPropertyInfo propertyInfo, object newValue)
3524 {
3525 SetProperty(propertyInfo, newValue);
3526 }
3527
3528 void IManageProperties.LoadProperty(IPropertyInfo propertyInfo, object newValue)
3529 {
3530 LoadProperty(propertyInfo, newValue);
3531 }
3532
3533 bool IManageProperties.LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
3534 {
3535 return LoadPropertyMarkDirty(propertyInfo, newValue);
3536 }
3537
3538 List<object> IManageProperties.GetChildren()
3539 {
3540 return FieldManager.GetChildren();
3541 }
3542#endregion
3543
3544#region MobileFormatter
3545
3556 [EditorBrowsable(EditorBrowsableState.Advanced)]
3558 {
3559 base.OnGetState(info, mode);
3560 info.AddValue("Csla.Core.BusinessBase._isNew", _isNew);
3561 info.AddValue("Csla.Core.BusinessBase._isDeleted", _isDeleted);
3562 info.AddValue("Csla.Core.BusinessBase._isDirty", _isDirty);
3563 info.AddValue("Csla.Core.BusinessBase._neverCommitted", _neverCommitted);
3564 info.AddValue("Csla.Core.BusinessBase._disableIEditableObject", _disableIEditableObject);
3565 info.AddValue("Csla.Core.BusinessBase._isChild", _isChild);
3566 info.AddValue("Csla.Core.BusinessBase._editLevelAdded", _editLevelAdded);
3567 info.AddValue("Csla.Core.BusinessBase._identity", _identity);
3568 }
3569
3580 [EditorBrowsable(EditorBrowsableState.Advanced)]
3582 {
3583 base.OnSetState(info, mode);
3584 _isNew = info.GetValue<bool>("Csla.Core.BusinessBase._isNew");
3585 _isDeleted = info.GetValue<bool>("Csla.Core.BusinessBase._isDeleted");
3586 _isDirty = info.GetValue<bool>("Csla.Core.BusinessBase._isDirty");
3587 _neverCommitted = info.GetValue<bool>("Csla.Core.BusinessBase._neverCommitted");
3588 _disableIEditableObject = info.GetValue<bool>("Csla.Core.BusinessBase._disableIEditableObject");
3589 _isChild = info.GetValue<bool>("Csla.Core.BusinessBase._isChild");
3590 if (mode != StateMode.Undo)
3591 _editLevelAdded = info.GetValue<int>("Csla.Core.BusinessBase._editLevelAdded");
3592 _identity = info.GetValue<int>("Csla.Core.BusinessBase._identity");
3593 }
3594
3606 [EditorBrowsable(EditorBrowsableState.Advanced)]
3607 protected override void OnGetChildren(
3609 {
3610 base.OnGetChildren(info, formatter);
3611
3612 if (_fieldManager != null)
3613 {
3614 var fieldManagerInfo = formatter.SerializeObject(_fieldManager);
3615 info.AddChild("_fieldManager", fieldManagerInfo.ReferenceId);
3616 }
3617
3618 if (_businessRules != null)
3619 {
3620 var vrInfo = formatter.SerializeObject(_businessRules);
3621 info.AddChild("_businessRules", vrInfo.ReferenceId);
3622 }
3623 }
3624
3636 [EditorBrowsable(EditorBrowsableState.Advanced)]
3638 {
3639 if (info.Children.ContainsKey("_fieldManager"))
3640 {
3641 var childData = info.Children["_fieldManager"];
3642 _fieldManager = (FieldManager.FieldDataManager)formatter.GetObject(childData.ReferenceId);
3643 }
3644
3645 if (info.Children.ContainsKey("_businessRules"))
3646 {
3647 int refId = info.Children["_businessRules"].ReferenceId;
3648 _businessRules = (BusinessRules)formatter.GetObject(refId);
3649 }
3650
3651 base.OnSetChildren(info, formatter);
3652 }
3653
3654#endregion
3655
3656#region Property Checks ByPass
3657
3658 [NonSerialized]
3659 [NotUndoable]
3660 private bool _bypassPropertyChecks = false;
3661
3665 protected internal bool IsBypassingPropertyChecks { get { return _bypassPropertyChecks; } }
3666
3667 [NonSerialized]
3668 [NotUndoable]
3669 private BypassPropertyChecksObject _bypassPropertyChecksObject = null;
3670
3677 [DebuggerBrowsable(DebuggerBrowsableState.Never)]
3678 protected internal BypassPropertyChecksObject BypassPropertyChecks
3679 {
3680 get
3681 {
3682 return BypassPropertyChecksObject.GetManager(this);
3683 }
3684 }
3685
3692 [EditorBrowsable(EditorBrowsableState.Never)]
3693 protected internal class BypassPropertyChecksObject : IDisposable
3694 {
3695 private BusinessBase _businessObject;
3696 private static object _lock = new object();
3697
3698 internal BypassPropertyChecksObject(BusinessBase businessObject)
3699 {
3700 _businessObject = businessObject;
3701 _businessObject._bypassPropertyChecks = true;
3702 }
3703
3704#region IDisposable Members
3705
3709 public void Dispose()
3710 {
3711 Dispose(true);
3712 GC.SuppressFinalize(this);
3713 }
3714
3719 protected virtual void Dispose(bool dispose)
3720 {
3721 DeRef();
3722 }
3723
3729 public static BypassPropertyChecksObject GetManager(BusinessBase businessObject)
3730 {
3731 lock (_lock)
3732 {
3733 if (businessObject._bypassPropertyChecksObject == null)
3734 businessObject._bypassPropertyChecksObject = new BypassPropertyChecksObject(businessObject);
3735
3736 businessObject._bypassPropertyChecksObject.AddRef();
3737 }
3738 return businessObject._bypassPropertyChecksObject;
3739 }
3740
3741#region Reference counting
3742
3743 private int _refCount;
3744
3749 public int RefCount
3750 {
3751 get { return _refCount; }
3752 }
3753
3754 private void AddRef()
3755 {
3756 _refCount += 1;
3757 }
3758
3759 private void DeRef()
3760 {
3761
3762 lock (_lock)
3763 {
3764 _refCount -= 1;
3765 if (_refCount == 0)
3766 {
3767 _businessObject._bypassPropertyChecks = false;
3768 _businessObject._bypassPropertyChecksObject = null;
3769 _businessObject = null;
3770 }
3771 }
3772 }
3773
3774#endregion
3775#endregion
3776 }
3777
3778#endregion
3779
3780#region ISuppressRuleChecking Members
3781
3785 void ICheckRules.SuppressRuleChecking()
3786 {
3788 }
3789
3793 void ICheckRules.ResumeRuleChecking()
3794 {
3796 }
3797
3801 void ICheckRules.CheckRules()
3802 {
3804 }
3805
3809 Task ICheckRules.CheckRulesAsync()
3810 {
3812 }
3813
3818 {
3819 return BrokenRulesCollection;
3820 }
3821
3822 #endregion
3823 }
3824}
Provides consistent context information between the client and server DataPortal objects.
static PropertyChangedModes PropertyChangedMode
Gets or sets a value specifying how CSLA .NET should raise PropertyChanged events.
PropertyChangedModes
Enum representing the way in which CSLA .NET should raise PropertyChanged events.
IPrincipal User
Get or set the current IPrincipal object representing the user's identity.
virtual void OnMetaPropertyChanged(string propertyName)
virtual void OnUnknownPropertyChanged()
Call this method to raise the PropertyChanged event for all object properties.
virtual void OnPropertyChanging(string propertyName)
Call this method to raise the PropertyChanging event for a specific property.
This is the non-generic base class from which most business objects will be derived.
virtual void CheckObjectRules()
Check object rules and notifies UI of properties that may have changed.
virtual void OnBusyChanged(BusyChangedEventArgs args)
Raise the BusyChanged event.
Core.IParent Parent
Provide access to the parent reference for use in child object code.
void AddEventHooks(IBusinessObject child)
For internal use.
virtual bool IsPropertyBusy(Csla.Core.IPropertyInfo property)
Gets a value indicating whether a specific property is busy (has a currently executing async rule).
virtual bool IsSelfValid
Returns true if the object is currently valid, false if the object has broken rules or is otherwise i...
FieldDataManager FieldManager
Gets the PropertyManager object for this business object.
P LazyReadPropertyAsync< P >(PropertyInfo< P > property, Task< P > factory)
Gets a property's value as a specified type.
virtual bool CanExecuteMethod(string methodName)
Returns true if the user is allowed to execute the specified method.
void RemoveEventHooks(IBusinessObject child)
For internal use only.
virtual void Delete()
Marks the object for deletion.
virtual bool IsBusy
Gets a value indicating if this object or its child objects are busy.
virtual void OnUnhandledAsyncException(ErrorEventArgs error)
Raises the UnhandledAsyncException event.
P LazyGetPropertyAsync< P >(PropertyInfo< P > property, Task< P > factory)
Lazily initializes a property and returns the resulting value.
void ApplyEdit()
Commits the current edit process.
virtual bool IsValid
Returns true if the object and its child objects are currently valid, false if the object or any of i...
virtual void EditChildComplete(Core.IEditableBusinessObject child)
Override this method to be notified when a child object's Core.BusinessBase.ApplyEdit method has comp...
override void OnPropertyChanged(IPropertyInfo propertyInfo)
Call this method to raise the PropertyChanged event for a specific property.
virtual void Child_OnDataPortalInvoke(DataPortalEventArgs e)
Called by the server-side DataPortal prior to calling the requested DataPortal_XYZ method.
bool IsDeleted
Returns true if this object is marked for deletion.
object GetProperty(IPropertyInfo propertyInfo)
Gets a property's value as a specified type.
bool IsPropertyBusy(string propertyName)
Gets a value indicating whether a specific property is busy (has a currently executing async rule).
void MarkAsChild()
Marks the object as being a child object.
static MethodInfo RegisterMethod(Type objectType, string methodName)
Indicates that the specified method belongs to the type.
virtual object GetClone()
Creates a clone of the object.
P LazyGetProperty< P >(PropertyInfo< P > property, Func< P > valueGenerator)
Lazily initializes a property and returns the resulting value.
bool DisableIEditableObject
Gets or sets a value indicating whether the IEditableObject interface methods should be disabled for ...
virtual void AddBusinessRules()
Override this method in your business class to be notified when you need to set up shared business ru...
EventHandler ValidationComplete
Event raised when validation is complete.
void SetPropertyConvert< P, V >(PropertyInfo< P > propertyInfo, ref P field, V newValue)
Sets a property's backing field with the supplied value, first checking authorization,...
virtual void OnRemoveEventHooks(IBusinessObject child)
Unhook child object events.
P LazyReadProperty< P >(PropertyInfo< P > property, Func< P > valueGenerator)
Gets a property's value as a specified type.
virtual void OnErrorsChanged(string propertyName)
Call to indicate that errors have changed for a property.
virtual bool IsSelfBusy
Gets a value indicating if this object is busy.
virtual void OnValidationComplete()
Raises the ValidationComplete event
BusinessRuleManager GetRegisteredRules()
Gets the registered rules.
virtual object ReadProperty(IPropertyInfo propertyInfo)
Gets a property's value.
void SetProperty< P >(PropertyInfo< P > propertyInfo, ref P field, P newValue)
Sets a property's backing field with the supplied value, first checking authorization,...
override void OnSetState(Csla.Serialization.Mobile.SerializationInfo info, StateMode mode)
Override this method to retrieve your field values from the MobileFormatter serialzation stream.
virtual void Child_OnDataPortalException(DataPortalEventArgs e, Exception ex)
Called by the server-side DataPortal if an exception occurs during data access.
BrokenRulesCollection GetBrokenRules()
Gets the broken rules for this object
BusinessRules BusinessRules
Provides access to the broken rules functionality.
bool CanExecuteMethod(Csla.Core.IMemberInfo method, bool throwOnFalse)
Returns true if the user is allowed to execute the specified method.
void LoadPropertyAsync< R >(PropertyInfo< R > property, Task< R > factory)
Load a property from an async method.
BusinessBase()
Creates an instance of the type.
virtual void Child_Create()
Override this method to load a new business object with default values from the database.
void MarkDeleted()
Marks an object for deletion.
virtual bool CanExecuteMethod(Csla.Core.IMemberInfo method)
Returns true if the user is allowed to execute the specified method.
void SetPropertyConvert< P, F >(PropertyInfo< P > propertyInfo, F newValue)
Sets a property's managed field with the supplied value, first checking authorization,...
void CancelEdit()
Cancels the current edit process, restoring the object's state to its previous values.
virtual void LoadProperty(IPropertyInfo propertyInfo, object newValue)
Loads a property's managed field with the supplied value.
virtual void OnChildChanged(ChildChangedEventArgs e)
Raises the ChildChanged event, indicating that a child object has been changed.
virtual bool LoadPropertyMarkDirty(IPropertyInfo propertyInfo, object newValue)
Loads a property's managed field with the supplied value.
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...
bool CanReadProperty(string propertyName)
Returns true if the user is allowed to read the specified property.
EventHandler< Csla.Core.ChildChangedEventArgs > ChildChanged
Event raised when a child object has been changed.
bool IsNew
Returns true if this is a new object, false if it is a pre-existing object.
override void OnGetChildren(Csla.Serialization.Mobile.SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter)
Override this method to insert your child object references into the MobileFormatter serialzation str...
void MarkDirty(bool suppressEvent)
Marks an object as being dirty, or changed.
virtual bool IsSavable
Returns true if this object is both dirty and valid.
BusyChangedEventHandler BusyChanged
Event indicating that the IsBusy property has changed.
virtual void SetParent(Core.IParent parent)
Used by BusinessListBase as a child object is created to tell the child object about its parent.
virtual void MarkOld()
Marks the object as being an old (not new) object.
virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
This method is called on a newly deserialized object after deserialization is complete.
static Csla.Core.IMemberInfo RegisterMethod(Type objectType, IMemberInfo info)
Indicates that the specified method belongs to the type.
virtual bool IsSelfDirty
Returns true if this object's data has been changed.
EventHandler< ErrorEventArgs > UnhandledAsyncException
Event indicating that an exception occurred during the processing of an async operation.
virtual void PropertyHasChanged(Csla.Core.IPropertyInfo property)
Performs processing required when a property has changed.
virtual bool CanWriteProperty(Csla.Core.IPropertyInfo property)
Returns true if the user is allowed to write the specified property.
virtual Rules.BrokenRulesCollection BrokenRulesCollection
Provides access to the readonly collection of broken business rules for this object.
virtual bool CanReadProperty(Csla.Core.IPropertyInfo property)
Returns true if the user is allowed to read the calling property.
override void UndoChangesComplete()
Called when an undo operation has completed.
override void OnApplicationContextSet()
Method invoked after ApplicationContext is available.
void MarkDirty()
Marks an object as being dirty, or changed.
override void AcceptChangesComplete()
Notifies the parent object (if any) that this child object's edits have been accepted.
static PropertyInfo< P > RegisterProperty< P >(Type objectType, PropertyInfo< P > info)
Indicates that the specified property belongs to the type.
virtual void MetaPropertyHasChanged(string name)
Raises OnPropertyChanged for meta properties (IsXYZ) when PropertyChangedMode is not Windows
P GetProperty< P >(string propertyName, P field, P defaultValue)
Gets a property's value, first checking authorization.
virtual void DataPortal_OnDataPortalInvoke(DataPortalEventArgs e)
Called by the server-side DataPortal prior to calling the requested DataPortal_XYZ method.
void LoadPropertyConvert< P, F >(PropertyInfo< P > propertyInfo, F newValue)
Loads a property's managed field with the supplied value.
virtual void DataPortal_OnDataPortalInvokeComplete(DataPortalEventArgs e)
Called by the server-side DataPortal after calling the requested DataPortal_XYZ method.
P GetPropertyConvert< F, P >(PropertyInfo< F > propertyInfo, F field)
Gets a property's value as a specified type, first checking authorization.
virtual void OnAddEventHooks(IBusinessObject child)
Hook child object events.
void OnUnhandledAsyncException(object originalSender, Exception error)
Raises the UnhandledAsyncException event.
override void OnGetState(Csla.Serialization.Mobile.SerializationInfo info, StateMode mode)
Override this method to insert your field values into the MobileFormatter serialzation stream.
bool LoadPropertyMarkDirty< P >(PropertyInfo< P > propertyInfo, P newValue)
Loads a property's managed field with the supplied value and mark field as dirty if value is modified...
bool IsChild
Returns true if this is a child (non-root) object.
virtual bool IsDirty
Returns true if this object's data, or any of its fields or child objects data, has been changed.
virtual void CheckPropertyRules(IPropertyInfo property)
Check rules for the property and notifies UI of properties that may have changed.
bool CanWriteProperty(Csla.Core.IPropertyInfo property, bool throwOnFalse)
Returns true if the user is allowed to write the calling property.
virtual void Initialize()
Override this method to set up event handlers so user code in a partial class can respond to events r...
virtual void DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)
Called by the server-side DataPortal if an exception occurs during data access.
void MarkClean()
Forces the object's IsDirty flag to false.
void MarkIdle()
Mark the object as not busy (it is not running an async operation).
void MarkBusy()
Mark the object as busy (it is running an async operation).
void BeginEdit()
Starts a nested edit on the object.
void SetProperty(IPropertyInfo propertyInfo, object newValue)
Sets a property's managed field with the supplied value, and then calls PropertyHasChanged if the val...
virtual void Child_OnDataPortalInvokeComplete(DataPortalEventArgs e)
Called by the server-side DataPortal after calling the requested DataPortal_XYZ method.
P ReadProperty< P >(PropertyInfo< P > propertyInfo)
Gets a property's value as a specified type.
bool CanWriteProperty(string propertyName)
Returns true if the user is allowed to write the specified property.
bool PropertyIsLoading(IPropertyInfo propertyInfo)
Gets a value indicating whether a lazy loaded property is currently being retrieved.
virtual void MarkNew()
Marks the object as being a new object.
bool CanReadProperty(Csla.Core.IPropertyInfo property, bool throwOnFalse)
Returns true if the user is allowed to read the calling property.
override void OnSetChildren(Csla.Serialization.Mobile.SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter)
Override this method to retrieve your child object references from the MobileFormatter serialzation s...
Event arguments for the BusyChanged event.
Contains event data about the changed child object.
Event arguments for an unhandled async exception.
Manages properties and property data for a business object.
bool HasFields
Gets a value indicating whether there are any managed fields available.
List< IPropertyInfo > GetRegisteredProperties()
Returns a copy of the property list for the business object.
FieldDataManager()
Creates an instance of the type.
bool IsDirty()
Returns a value indicating whether any fields are dirty.
IFieldData GetFieldData(IPropertyInfo propertyInfo)
Gets the IFieldData object for a specific field.
bool IsValid()
Returns a value indicating whether all fields are valid.
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.
IPropertyInfo GetRegisteredProperty(string propertyName)
Returns the IPropertyInfo object corresponding to the property name.
Implements n-level undo capabilities as described in Chapters 2 and 3.
Definition: UndoableBase.cs:27
bool BindingEdit
Gets or sets a value indicating whether n-level undo was invoked through IEditableObject.
Definition: UndoableBase.cs:73
UndoableBase()
Creates an instance of the type.
Definition: UndoableBase.cs:61
Provides information about the DataPortal call.
Maintains metadata about a method.
Definition: MethodInfo.cs:19
A strongly-typed resource class, for looking up localized strings, etc.
static string PrivateFieldException
Looks up a localized string similar to Properties with private backing fields must be marked as Relat...
static string NoDeleteRootException
Looks up a localized string similar to Invalid for root objects - use Delete instead.
static string PropertySetNotAllowed
Looks up a localized string similar to Property set not allowed.
static string ChildDeleteException
Looks up a localized string similar to Can not directly mark a child object for deletion - use its pa...
static string PropertyLoadException
Looks up a localized string similar to Property load or set failed for property {0} ({1}).
static string PropertyGetNotAllowed
Looks up a localized string similar to Property get not allowed.
static string BusyObjectsMayNotBeMarkedBusy
Looks up a localized string similar to Objects that are marked busy may not be marked busy again.
static string NoSuchMethod
Looks up a localized string similar to No such method {0}.
Maintains metadata about a property.
virtual T DefaultValue
Gets the default initial value for the 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.
string Name
Gets the property name value.
Exception indicating a failure to set a property's field.
string Description
Provides access to the description of the broken rule.
Definition: BrokenRule.cs:55
A collection of currently broken rules.
BrokenRule GetFirstBrokenRule(Csla.Core.IPropertyInfo property)
Returns the first BrokenRule object corresponding to the specified property.
override string ToString()
Returns the text of all broken rule descriptions, each separated by a Environment....
Manages the list of rules for a business type.
Tracks the business rules for a business object.
BusinessRules()
Creates an instance of the type.
List< string > CheckRules()
Invokes all rules for the business type.
override void OnSetChildren(SerializationInfo info, MobileFormatter formatter)
Override this method to retrieve your child object references from the MobileFormatter serialzation s...
async Task< List< string > > CheckRulesAsync(int timeout)
Invokes all rules for the business type.
bool SuppressRuleChecking
Gets or sets a value indicating whether calling CheckRules should result in rule methods being invoke...
bool IsValid
Gets a value indicating whether there are any currently broken rules, which would mean the object is ...
List< string > CheckObjectRules()
Invokes all rules attached at the class level of the business type.
void AddDataAnnotations()
Adds validation rules corresponding to property data annotation attributes.
static bool HasPermission(ApplicationContext applicationContext, AuthorizationActions action, Type objectType)
Checks per-type authorization rules.
bool GetPropertyBusy(Csla.Core.IPropertyInfo property)
Gets a value indicating whether a specific property has any async rules running.
bool RunningAsyncRules
Gets a value indicating whether any async rules are currently executing.
bool CachePermissionResult(AuthorizationActions action, IMemberInfo element)
Gets a value indicating whether the permission result can be cached.
BrokenRulesCollection GetBrokenRules()
Gets the broken rules list.
Serializes and deserializes objects at the field level.
Object containing the serialization data for a specific object.
object Value
Gets or sets the field value.
Definition: IFieldData.cs:27
This is the core interface implemented by all CSLA .NET base classes.
int Identity
Gets a value representing this object instance's unique identity value within the business object gra...
Defines the common methods for any business object which exposes means to supress and check business ...
Definition: ICheckRules.cs:18
Defines the common methods required by all editable CSLA single objects.
Defines the common methods required by all editable CSLA collection objects.
Maintains metadata about a method or property.
Definition: IMemberInfo.cs:19
string Name
Gets the member name value.
Definition: IMemberInfo.cs:23
Interface defining an object that notifies when it is busy executing an asynchronous operation.
Definition: INotifyBusy.cs:17
BusyChangedEventHandler BusyChanged
Event raised when the object's busy status changes.
Definition: INotifyBusy.cs:22
Implemented by classes that notify when a child object has changed.
EventHandler< ChildChangedEventArgs > ChildChanged
Event indictating that a child object has changed.
Implemented by an object that perfoms asynchronous operations that may raise exceptions.
EventHandler< ErrorEventArgs > UnhandledAsyncException
Event indicating that an exception occurred during an asynchronous operation.
Defines the interface that must be implemented by any business object that contains child objects.
Definition: IParent.cs:18
int GetNextIdentity(int current)
Gets and consumes the next available unique identity value for an object instance in the object graph...
void ApplyEditChild(Core.IEditableBusinessObject child)
Override this method to be notified when a child object's Core.BusinessBase.ApplyEdit method has comp...
void RemoveChild(Core.IEditableBusinessObject child)
This method is called by a child object when it wants to be removed from the collection.
IParent Parent
Provide access to the parent reference for use in child object code.
Definition: IParent.cs:39
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.
Defines the interaction between the rules engine and a business object that hosts the rules.
Definition: IHostRules.cs:20
void RuleComplete(Csla.Core.IPropertyInfo property)
Indicates that a rule has finished processing.
void RuleStart(Csla.Core.IPropertyInfo property)
Indicates that a rule has started processing.
Defines the authorization interface through which an object can indicate which properties the current...
Interface defining callback methods used by the SerializationFormatterFactory.GetFormatter().
void Deserialized()
Method called on an object after deserialization is complete.
delegate void BusyChangedEventHandler(object sender, BusyChangedEventArgs e)
Delegate for handling the BusyChanged event.
StateMode
Indicates the reason the MobileFormatter functionality has been invoked.
Definition: StateMode.cs:20
AuthorizationActions
Authorization actions.
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.