Skip to content

Commit a478b2d

Browse files
committed
Serialize #2 - Cloning - StringHelper - type conversion
1 parent 103da2c commit a478b2d

File tree

19 files changed

+441
-93
lines changed

19 files changed

+441
-93
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Runtime.Serialization;
7+
using SharpApi.Helpers.ValueTypeExtensions;
8+
9+
namespace SharpApi.Helpers.ObjectExtensions.Cloning
10+
{
11+
public static class Cloning
12+
{
13+
#region Private Properties
14+
15+
private const BindingFlags Binding = BindingFlags.Instance |
16+
BindingFlags.NonPublic | BindingFlags.Public |
17+
BindingFlags.FlattenHierarchy;
18+
19+
#endregion
20+
21+
public static T Clone<T>(this object? istance, ICollection<string>? propertyExcludeList = null)
22+
{
23+
if (istance == null)
24+
return default;
25+
26+
return (T)DeepClone(istance, propertyExcludeList);
27+
}
28+
29+
public static object? Clone(this object? istance)
30+
{
31+
return DeepClone(istance);
32+
}
33+
34+
#region Privat Method Deep Clone
35+
36+
// Clone the object Properties and its children recursively
37+
private static object? DeepClone(object? istance, ICollection<string>? propertyExcludeList = null)
38+
{
39+
if (istance is null) return null;
40+
41+
var desireObjectToBeCloned = istance;
42+
43+
var primaryType = istance.GetType();
44+
45+
if (primaryType.IsArray)
46+
return ((Array)desireObjectToBeCloned).Clone();
47+
48+
object tObject = desireObjectToBeCloned as IList;
49+
if (tObject != null)
50+
{
51+
var properties = primaryType.GetProperties();
52+
// Get the IList Type of the object
53+
var customList = typeof(List<>).MakeGenericType
54+
((properties[^1]).PropertyType);
55+
tObject = (IList)Activator.CreateInstance(customList);
56+
var list = (IList)tObject;
57+
// loop throw each object in the list and clone it
58+
foreach (var item in ((IList)desireObjectToBeCloned))
59+
{
60+
if (item == null)
61+
continue;
62+
var value = DeepClone(item, propertyExcludeList);
63+
list?.Add(value);
64+
}
65+
}
66+
else
67+
{
68+
// if the item is a string then Clone it and return it directly.
69+
if (primaryType == typeof(string))
70+
return (desireObjectToBeCloned as string)?.Clone();
71+
72+
// Create an empty object and ignore its construtore.
73+
tObject = FormatterServices.GetUninitializedObject(primaryType);
74+
var fields = desireObjectToBeCloned.GetType().GetFields(Binding);
75+
foreach (var property in fields)
76+
{
77+
if ((propertyExcludeList != null) && (propertyExcludeList.Any()))
78+
if (propertyExcludeList.Contains(property.Name.ExtractBetween("<", ">").FirstOrDefault()))
79+
continue;
80+
81+
if (property.IsInitOnly) // Validate if the property is a writable one.
82+
continue;
83+
var value = property.GetValue(desireObjectToBeCloned);
84+
if (property.FieldType.IsClass && property.FieldType != typeof(string))
85+
tObject.GetType().GetField(property.Name, Binding)?.SetValue
86+
(tObject, DeepClone(value, propertyExcludeList));
87+
else
88+
tObject.GetType().GetField(property.Name, Binding)?.SetValue(tObject, value);
89+
}
90+
}
91+
92+
return tObject;
93+
}
94+
95+
#endregion
96+
}
97+
}

src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Deserialize/FromJson.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Deserialize/FromJsonNewtonSoft.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.IO;
2+
using System.Runtime.Serialization.Formatters.Binary;
3+
4+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
5+
{
6+
public static partial class Deserialize
7+
{
8+
/// <summary>
9+
/// Given a byte array, this method returns the specified object
10+
/// </summary>
11+
/// <param name="istance">Array of byte</param>
12+
/// <returns></returns>
13+
public static T FromByteArray<T>(this byte[]? istance)
14+
{
15+
if (istance == null) return default;
16+
17+
using var memoryStream = new MemoryStream(istance);
18+
var binaryFormatter = new BinaryFormatter();
19+
var tempObject = binaryFormatter.Deserialize(memoryStream);
20+
21+
return tempObject.GetType() == typeof(T) ? (T) tempObject : default;
22+
}
23+
}
24+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Text.Json;
3+
using Newtonsoft.Json;
4+
using SharpApi.Helpers.Model.Enum;
5+
6+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
7+
{
8+
public static partial class Deserialize
9+
{
10+
/// <summary>
11+
/// This method deserializes the JSON to the specific object
12+
/// </summary>
13+
/// <typeparam name="T"></typeparam>
14+
/// <param name="istance"></param>
15+
/// <param name="serializeApiType"></param>
16+
/// <returns></returns>
17+
private static T? FromJson<T>(this string istance, SerializeApiType serializeApiType = SerializeApiType.NewtonSoft)
18+
where T : class
19+
{
20+
if (string.IsNullOrEmpty(istance)) return default;
21+
22+
return serializeApiType == SerializeApiType.NewtonSoft
23+
? JsonConvert.DeserializeObject<T>(istance)
24+
: System.Text.Json.JsonSerializer.Deserialize<T>(istance);
25+
}
26+
27+
public static T? FromJson<T>(this string istance, object? serializeContext = null,
28+
SerializeApiType serializeApiType = SerializeApiType.NewtonSoft)
29+
where T : class
30+
{
31+
if (string.IsNullOrEmpty(istance)) return default;
32+
33+
if (serializeContext == null)
34+
return istance.FromJson<T>(serializeApiType);
35+
36+
return serializeContext switch
37+
{
38+
JsonSerializerOptions t => istance.FromJson<T>(t),
39+
JsonConverter[] tarr => istance.FromJson<T>(tarr),
40+
JsonSerializerSettings ts => istance.FromJson<T>(ts),
41+
_ => throw new NotImplementedException()
42+
};
43+
}
44+
}
45+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Newtonsoft.Json;
2+
3+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
4+
{
5+
public static partial class Deserialize
6+
{
7+
/// <summary>
8+
/// This method deserializes the JSON to the specific object
9+
/// </summary>
10+
/// <typeparam name="T"></typeparam>
11+
/// <param name="istance"></param>
12+
/// <param name="settings"></param>
13+
/// <returns></returns>
14+
private static T? FromJson<T>(this string istance,JsonSerializerSettings settings) where T : class
15+
{
16+
return string.IsNullOrEmpty(istance) ? default : JsonConvert.DeserializeObject<T>(istance, settings);
17+
}
18+
19+
/// <summary>
20+
/// This method deserializes the JSON to the specific object
21+
/// </summary>
22+
/// <typeparam name="T"></typeparam>
23+
/// <param name="istance"></param>
24+
/// <param name="converters">Converters to use while deserializing.</param>
25+
/// <returns></returns>
26+
private static T? FromJson<T>(this string istance, params JsonConverter[] converters) where T : class
27+
{
28+
return string.IsNullOrEmpty(istance) ? default : JsonConvert.DeserializeObject<T>(istance, converters);
29+
}
30+
}
31+
}

src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Deserialize/FromJsonSystemText.cs renamed to src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Serialization/Deserialize/FromJsonSystemText.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Text.Json;
22

3-
namespace SharpApi.Helpers.ObjectExtensions.Deserialize
3+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
44
{
55
public static partial class Deserialize
66
{
@@ -11,7 +11,7 @@ public static partial class Deserialize
1111
/// <param name="istance"></param>
1212
/// <param name="options"></param>
1313
/// <returns></returns>
14-
public static T FromJson<T>(this string istance,JsonSerializerOptions options) where T : class
14+
private static T? FromJson<T>(this string istance,JsonSerializerOptions options) where T : class
1515
{
1616
return string.IsNullOrEmpty(istance) ? default : JsonSerializer.Deserialize<T>(istance, options);
1717
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.IO;
3+
using System.Runtime.Serialization.Formatters.Binary;
4+
5+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
6+
{
7+
public static partial class Serialize
8+
{
9+
/// <summary>
10+
/// Given an object, this method returns an Array of <see cref="byte"/>
11+
/// </summary>
12+
/// <param name="value"></param>
13+
/// <returns></returns>
14+
public static byte[] ToByteArray(this object? value)
15+
{
16+
if (value is null) return new byte[0];
17+
18+
using var memoryStream = new MemoryStream();
19+
20+
var binaryFormatter = new BinaryFormatter();
21+
binaryFormatter.Serialize(memoryStream, value);
22+
23+
return memoryStream.ToArray();
24+
}
25+
}
26+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Text.Json;
3+
using Newtonsoft.Json;
4+
using SharpApi.Helpers.Model.Enum;
5+
6+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
7+
{
8+
public static partial class Serialize
9+
{
10+
/// <summary>
11+
/// This method serializes the specific object to JSON
12+
/// </summary>
13+
/// <param name="istance"></param>
14+
/// <param name="serializeApiType"></param>
15+
/// <returns></returns>
16+
public static string ToJson(this object? istance,
17+
SerializeApiType serializeApiType = SerializeApiType.NewtonSoft)
18+
{
19+
return (istance is null)
20+
? string.Empty
21+
: serializeApiType == SerializeApiType.NewtonSoft
22+
? JsonConvert.SerializeObject(istance)
23+
: System.Text.Json.JsonSerializer.Serialize(istance);
24+
25+
}
26+
27+
public static string ToJson(this object? istance, object serializeContext)
28+
{
29+
if (istance is null) return string.Empty;
30+
31+
return serializeContext switch
32+
{
33+
JsonSerializerOptions t => istance.ToJson(t),
34+
JsonSerializerSettings ts => istance.ToJson(ts),
35+
_ => throw new NotImplementedException()
36+
};
37+
}
38+
}
39+
}

src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Serialize/ToJsonNewtonSoft.cs renamed to src/Helpers/src/SharpApi.Helpers/ObjectExtensions/Serialization/Serialize/ToJsonNewtonSoft.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Newtonsoft.Json;
22

3-
namespace SharpApi.Helpers.ObjectExtensions.Serialize
3+
namespace SharpApi.Helpers.ObjectExtensions.Serialization
44
{
55
public static partial class Serialize
66
{
@@ -10,7 +10,7 @@ public static partial class Serialize
1010
/// <param name="istance"></param>
1111
/// <param name="settings"></param>
1212
/// <returns></returns>
13-
public static string ToJson(this object istance, JsonSerializerSettings settings)
13+
private static string ToJson(this object? istance, JsonSerializerSettings settings)
1414
{
1515
return istance == null ? string.Empty : JsonConvert.SerializeObject(istance, settings);
1616
}

0 commit comments

Comments
 (0)