Skip to content

Commit

Permalink
#115 refactor: clone logic for icloneable properties moved to utils c…
Browse files Browse the repository at this point in the history
…lass
  • Loading branch information
joseantmazonsb committed Feb 27, 2022
1 parent 8af502d commit 65797d1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
15 changes: 4 additions & 11 deletions Linguard/Core/Configuration/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Linguard.Core.Configuration;
using Linguard.Core.Utils;

namespace Linguard.Core.Configuration;

public class Configuration : IConfiguration {
public IWireguardConfiguration Wireguard { get; set; } = new WireguardConfiguration();
Expand All @@ -7,15 +9,6 @@ public class Configuration : IConfiguration {
public ITrafficConfiguration Traffic { get; set; } = new TrafficConfiguration();

public object Clone() {
var clone = (IConfiguration) MemberwiseClone();
var cloneableProperties = GetType().GetProperties()
.Where(p => p.PropertyType.GetInterfaces().Contains(typeof(ICloneable)));
foreach (var property in cloneableProperties) {
var propertyValue = property.GetValue(this);
var propertyClone = propertyValue?.GetType().GetMethod(nameof(Clone))
!.Invoke(propertyValue, Array.Empty<object>());
property.SetValue(clone, propertyClone);
}
return clone;
return Cloning.Clone(this);
}
}
25 changes: 25 additions & 0 deletions Linguard/Core/Utils/Cloning.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Linguard.Core.Utils;

public static class Cloning {

/// <summary>
/// Clone an object with properties that implement <c>ICloneable</c>.
/// </summary>
/// <remarks>Properties that do not implement <c>ICloneable</c> won't be cloned.</remarks>
/// <remarks>The type must have a parameterless constructor.</remarks>
/// <param name="original"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Clone<T>(T original) where T : new() {
var clone = Activator.CreateInstance<T>();
var cloneableProperties = original!.GetType().GetProperties()
.Where(p => p.PropertyType.GetInterfaces().Contains(typeof(ICloneable)));
foreach (var property in cloneableProperties) {
var propertyValue = property.GetValue(original);
var propertyClone = propertyValue?.GetType().GetMethod(nameof(Clone))
!.Invoke(propertyValue, Array.Empty<object>());
property.SetValue(clone, propertyClone);
}
return clone;
}
}

0 comments on commit 65797d1

Please sign in to comment.