From c7976fb96042487c7804a533811d9def8ae1db84 Mon Sep 17 00:00:00 2001 From: smolchanovsky Date: Sat, 20 Oct 2018 13:25:24 +0500 Subject: [PATCH 1/2] add cloner class --- DeepCloner/Cloner.cs | 51 +++++++++++++++++++++++++ DeepCloner/DeepCloner.csproj | 2 + DeepCloner/DeepClonerExtensions.cs | 30 +-------------- DeepCloner/Helpers/PermissionChecker.cs | 36 +++++++++++++++++ 4 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 DeepCloner/Cloner.cs create mode 100644 DeepCloner/Helpers/PermissionChecker.cs diff --git a/DeepCloner/Cloner.cs b/DeepCloner/Cloner.cs new file mode 100644 index 0000000..f59dca7 --- /dev/null +++ b/DeepCloner/Cloner.cs @@ -0,0 +1,51 @@ +using Force.DeepCloner.Helpers; + +namespace Force.DeepCloner +{ + /// + /// Performs copy of object + /// + public class Cloner + { + public Cloner() + { + PermissionChecker.ThrowIfNoPermission(); + } + + /// + /// Performs deep (full) copy of object and related graph + /// + public T DeepClone(T obj) + { + return DeepClonerGenerator.CloneObject(obj); + } + + /// + /// Performs deep (full) copy of object and related graph to existing object + /// + /// existing filled object + /// Method is valid only for classes, classes should be descendants in reality, not in declaration + public TTo DeepCloneTo(TFrom objFrom, TTo objTo) where TTo : class, TFrom + { + return (TTo)DeepClonerGenerator.CloneObjectTo(objFrom, objTo, true); + } + + /// + /// Performs shallow copy of object to existing object + /// + /// existing filled object + /// Method is valid only for classes, classes should be descendants in reality, not in declaration + public TTo ShallowCloneTo(TFrom objFrom, TTo objTo) where TTo : class, TFrom + { + return (TTo)DeepClonerGenerator.CloneObjectTo(objFrom, objTo, false); + } + + /// + /// Performs shallow (only new object returned, without cloning of dependencies) copy of object + /// + public static T ShallowClone(T obj) + { + return ShallowClonerGenerator.CloneObject(obj); + } + } +} \ No newline at end of file diff --git a/DeepCloner/DeepCloner.csproj b/DeepCloner/DeepCloner.csproj index b1ad2f9..29e2c8c 100644 --- a/DeepCloner/DeepCloner.csproj +++ b/DeepCloner/DeepCloner.csproj @@ -44,6 +44,7 @@ + @@ -53,6 +54,7 @@ + diff --git a/DeepCloner/DeepClonerExtensions.cs b/DeepCloner/DeepClonerExtensions.cs index 60df9a1..defccf7 100644 --- a/DeepCloner/DeepClonerExtensions.cs +++ b/DeepCloner/DeepClonerExtensions.cs @@ -1,7 +1,4 @@ -using System; -using System.Security; - -using Force.DeepCloner.Helpers; +using Force.DeepCloner.Helpers; namespace Force.DeepCloner { @@ -48,30 +45,7 @@ public static T ShallowClone(this T obj) static DeepClonerExtensions() { - if (!PermissionCheck()) - { - throw new SecurityException("DeepCloner should have enough permissions to run. Grant FullTrust or Reflection permission."); - } - } - - private static bool PermissionCheck() - { - // best way to check required permission: execute something and receive exception - // .net security policy is weird for normal usage - try - { - new object().ShallowClone(); - } - catch (VerificationException) - { - return false; - } - catch (MemberAccessException) - { - return false; - } - - return true; + PermissionChecker.ThrowIfNoPermission(); } } } diff --git a/DeepCloner/Helpers/PermissionChecker.cs b/DeepCloner/Helpers/PermissionChecker.cs new file mode 100644 index 0000000..8175618 --- /dev/null +++ b/DeepCloner/Helpers/PermissionChecker.cs @@ -0,0 +1,36 @@ +using System; +using System.Security; + +namespace Force.DeepCloner.Helpers +{ + internal static class PermissionChecker + { + public static void ThrowIfNoPermission() + { + if (!CheckPermission()) + { + throw new SecurityException("DeepCloner should have enough permissions to run. Grant FullTrust or Reflection permission."); + } + } + + public static bool CheckPermission() + { + // best way to check required permission: execute something and receive exception + // .net security policy is weird for normal usage + try + { + DeepClonerGenerator.CloneObject(new object()); + } + catch (VerificationException) + { + return false; + } + catch (MemberAccessException) + { + return false; + } + + return true; + } + } +} \ No newline at end of file From ca94050761693504b101576a63e6ebf31803d002 Mon Sep 17 00:00:00 2001 From: smolchanovsky Date: Sun, 22 Dec 2019 11:34:16 +0500 Subject: [PATCH 2/2] add interface ICloner --- DeepCloner/Cloner.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/DeepCloner/Cloner.cs b/DeepCloner/Cloner.cs index f59dca7..58076a4 100644 --- a/DeepCloner/Cloner.cs +++ b/DeepCloner/Cloner.cs @@ -2,10 +2,35 @@ namespace Force.DeepCloner { + /// + /// Interface for classes capable to perform copy of object + /// + public interface ICloner + { + /// + /// Performs deep (full) copy of object and related graph + /// + T DeepClone(T obj); + + /// + /// Performs deep (full) copy of object and related graph to existing object + /// + /// existing filled object + /// Method is valid only for classes, classes should be descendants in reality, not in declaration + TTo DeepCloneTo(TFrom objFrom, TTo objTo) where TTo : class, TFrom; + + /// + /// Performs shallow copy of object to existing object + /// + /// existing filled object + /// Method is valid only for classes, classes should be descendants in reality, not in declaration + TTo ShallowCloneTo(TFrom objFrom, TTo objTo) where TTo : class, TFrom; + } + /// /// Performs copy of object /// - public class Cloner + public class Cloner : ICloner { public Cloner() {