CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
GraphMerger.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="GrapherMerger.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Defines members required for smart</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections;
10using System.Collections.Generic;
11using System.Linq;
12
13namespace Csla.Core
14{
19 public class GraphMerger : Csla.Server.ObjectFactory
20 {
27 {
28 if (target is IManageProperties imp)
29 {
30 var targetProperties = imp.GetManagedProperties();
31 foreach (var item in targetProperties)
32 {
33 var sourceValue = ReadProperty(source, item);
34 if (sourceValue is IEditableBusinessObject sourceChild)
35 {
36 if (ReadProperty(target, item) is IEditableBusinessObject targetChild)
37 {
38 MergeGraph(targetChild, sourceChild);
39 }
40 else
41 {
42 if ((item.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
43 Csla.Reflection.MethodCaller.CallPropertySetter(target, item.Name, sourceChild);
44 else
45 LoadProperty(target, item, sourceChild);
46 }
47 }
48 else
49 {
50 if (sourceValue is IEditableCollection sourceList)
51 {
52 var targetList = ReadProperty(target, item) as IEditableCollection;
53 MergeGraph(targetList, sourceList);
54 }
55 else
56 {
57 if ((item.RelationshipType & RelationshipTypes.PrivateField) == RelationshipTypes.PrivateField)
58 Csla.Reflection.MethodCaller.CallPropertySetter(target, item.Name, sourceValue);
59 else
60 LoadProperty(target, item, sourceValue);
61 }
62 }
63 }
64 if (source.IsNew)
65 {
66 MarkNew(target);
67 }
68 else if (!source.IsDirty)
69 {
70 MarkOld(target);
71 }
72 else
73 {
74 CopyField(source, target, "_isDirty");
75 CopyField(source, target, "_isNew");
76 CopyField(source, target, "_isDeleted");
77 }
78 CheckRules(target);
79 }
80 }
81
82 private static void CopyField(object source, object target, string fieldName)
83 {
84 if (source == null) return;
85 if (target == null) return;
86 var sourceField = source.GetType().GetField(fieldName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
87 if (sourceField != null)
88 {
89 var targetField = target.GetType().GetField(fieldName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
90 if (targetField!= null)
91 {
92 targetField.SetValue(target, sourceField.GetValue(source));
93 }
94 }
95 }
96
102 private void MergeGraph(IEditableCollection target, IEditableCollection source)
103 {
104#if !NETFX_CORE
105 var listType = target.GetType();
106 var childType = Utilities.GetChildItemType(listType);
107 var genericTypeParams = new Type[] { listType, childType };
108 var parameterTypes = new Type[] { listType, listType };
109 var methodReference = this.GetType().GetMethod("MergeBusinessListGraph");
110 var gr = methodReference.MakeGenericMethod(genericTypeParams);
111 gr.Invoke(this, new object[] { target, source });
112#endif
113 }
114
120 public void MergeBusinessListGraph<T,C>(T target, T source)
121 where T : BusinessListBase<T,C>
122 where C : Core.IEditableBusinessObject
123 {
124 var deleted = new List<C>();
125 foreach (var item in target)
126 {
127 var sourceItem = source.Where(_ => _.Identity == item.Identity).FirstOrDefault();
128 if (sourceItem != null)
129 MergeGraph(item, sourceItem);
130 else
131 deleted.Add(item);
132 }
133
134 // add items not in target
135 foreach (var item in source)
136 if (target.Count(_ => _.Identity == item.Identity) == 0)
137 target.Add(item);
138
139 // remove items not in source
140 foreach (var item in deleted)
141 target.Remove(item);
142 GetDeletedList<C>(target).Clear();
143 }
144 }
145}
This is the base class from which most business collections or lists will be derived.
Implements behavior to merge one object graph into a clone of itself (typically post-serialization).
Definition: GraphMerger.cs:20
void MergeGraph(IEditableBusinessObject target, IEditableBusinessObject source)
Merges state from source graph into target graph.
Definition: GraphMerger.cs:26
void MergeBusinessListGraph< T, C >(T target, T source)
Merges state from source graph into target graph.
Definition: GraphMerger.cs:120
void MarkOld(object obj)
Calls the MarkOld method on the specified object, if possible.
void MarkNew(object obj)
Calls the MarkNew method on the specified object, if possible.
void LoadProperty(object obj, IPropertyInfo propertyInfo, object newValue)
Loads a property's managed field with the supplied value.
Csla.Core.MobileList< C > GetDeletedList< C >(object obj)
Gets the list of deleted items from an editable collection.
void CheckRules(object obj)
Calls the ValidationRules.CheckRules() method on the specified object, if possible.
object ReadProperty(object obj, IPropertyInfo propertyInfo)
Reads a property's managed field value.
Defines the common methods required by all editable CSLA single objects.
Defines the common methods required by all editable CSLA collection objects.
bool IsNew
Returns true if this is a new object, false if it is a pre-existing object.
bool IsDirty
Returns true if this object's data, or any of its fields or child objects data, has been changed.
Definition: ITrackStatus.cs:73
RelationshipTypes
List of valid relationship types between a parent object and another object through a managed propert...