C# Client Library
A C# Client Library for the AnalyzeRe REST API
Loading...
Searching...
No Matches
ExtensionMethods.IAPIType.cs
Go to the documentation of this file.
1using System;
2using System.Linq.Expressions;
3using System.Reflection;
4
7using Newtonsoft.Json;
8
9// ReSharper disable once CheckNamespace (Extension methods work best on the root namespace)
10namespace AnalyzeRe
11{
13 public static partial class ExtensionMethods
14 {
21 private static readonly AnalyzeReJsonConverter CloningSerializer;
22
23 static ExtensionMethods()
24 {
25 // For purposes of cloning an object, we need to also serialize its server-generated
26 // properties so that a new object can be constructed as though it were deserializing
27 // a JSON response from the server. Therefore, we change the serializer settings
28 // to use a new contract resolver that ignores server-generated properties.
29 CloningSerializer = new AnalyzeReJsonConverter();
30 CloningSerializer.SerializerSettings.ContractResolver =
31 new AnalyzeReSerializationContractResolver(ignoreServerGeneratedProperties: false);
32 // We must include null values in the serialized JSON so that members that normally
33 // get initialized to some non-null default (e.g. Lists and Dictionaries) will
34 // get overridden with null once again when deserializing the original's JSON.
35 CloningSerializer.SerializerSettings.NullValueHandling = NullValueHandling.Include;
36 CloningSerializer.DeserializerSettings.NullValueHandling = NullValueHandling.Include;
37 }
38
49 public static T ShallowCopy<T>(this T obj) where T : IAPIType
50 {
51 return obj.ShallowCopy<T>();
52 }
53
65 public static T DeepCopy<T>(this T obj) where T : IAPIType
66 {
67 string serializedObj = CloningSerializer.Serialize(obj);
68 if (typeof(T) == obj.GetType())
69 return CloningSerializer.Deserialize<T>(serializedObj);
70 // If the method invocation isn't strongly typed enough, the deserialize may fail,
71 // so call a deserializer with the explicit object type passed in, and cast the result
72 return (T)CloningSerializer.Deserialize(serializedObj, obj.GetType());
73 }
74
88 public static string Serialize(this IAPIType obj, bool pretty = false,
89 bool includeServerGeneratedProperties = true, bool includeNullProperties = false)
90 {
91 if(includeServerGeneratedProperties && includeNullProperties)
92 return CloningSerializer.Serialize(obj, pretty);
93 if (!includeServerGeneratedProperties && !includeNullProperties)
94 return AnalyzeReJsonConverter.Default.Serialize(obj, pretty);
96 if(includeServerGeneratedProperties)
97 converter.SerializerSettings.ContractResolver =
99 if (includeNullProperties)
100 {
101 converter.SerializerSettings.NullValueHandling = NullValueHandling.Include;
102 converter.DeserializerSettings.NullValueHandling = NullValueHandling.Include;
103 }
104 return converter.Serialize(obj, pretty);
105 }
106
117 public static T Change<T, TProperty>(
118 this T obj, Expression<Func<T, TProperty>> propertyExpression, TProperty newValue)
119 where T : IAPIType
120 {
121 PropertyInfo property;
122 string propertyName;
123 // First, get the property information from the expression given.
124 try
125 {
126 property = (PropertyInfo)ReflectionUtilities.GetMemberInfo(propertyExpression);
127 propertyName = property.Name;
128 }
129 catch (Exception ex)
130 {
131 throw new ArgumentException($"Error: Invalid property expression: {propertyExpression}", ex);
132 }
133 // If the PropertyInfo resolved is from a base class or interface, we must
134 // get the PropertyInfo for the concrete type corresponding to the obj instance.
135 Type runtimeType = obj.GetType();
136 Type declaringType = property.DeclaringType;
137 if (runtimeType != declaringType)
138 property = runtimeType.GetProperty(propertyName);
139 if (property == null)
140 throw new ArgumentException($"The property {propertyName} defined on the type " +
141 $"{declaringType.NiceTypeName()} could not be found on the object " +
142 $"supplied with the instance type {runtimeType.NiceTypeName()}");
143 // Finally, set the property value on the instance object provided.
144 try
145 {
146 property.SetValue(obj, newValue, null);
147 }
148 catch (Exception ex)
149 {
150 throw new ArgumentException("The supplied value of type " +
151 $"{newValue?.GetType().NiceTypeName() ?? "(null)"} is invalid for the " +
152 $"property {propertyName} on the type {runtimeType.NiceTypeName()}. " +
153 $"The expected type is {property.PropertyType.NiceTypeName()}", ex);
154 }
155
156 return obj;
157 }
158 }
159}
Provides the REST request methods available to data endpoints.
static string Serialize(this IAPIType obj, bool pretty=false, bool includeServerGeneratedProperties=true, bool includeNullProperties=false)
Returns the JSON representation of the current object.
static T DeepCopy< T >(this T obj)
Creates a clone of this object by serializing to JSON and then deserializing it to a new object....
static T ShallowCopy< T >(this T obj)
Makes a shallow copy of this object.
static T Change< T, TProperty >(this T obj, Expression< Func< T, TProperty > > propertyExpression, TProperty newValue)
Changes the specified property on the object (using reflection) and then returns the modified object.
A pre-configured RestSharp serializer / deserializer which is made to support parsing of AnalyzeRe AP...
static readonly AnalyzeReJsonConverter Default
Returns the default AnalyzeReJsonConverter instance.
string Serialize(object obj)
Serialize the object as JSON.
A custom property contract resolver which allows Server-Generated Analyze Re properties (ServerGenera...
Utilities that reflect on a type or property expression.
Interface shared by all object types and resources returned by the Analyze Re server.
Definition IAPIType.cs:6