diff --git a/DeepCloner/Cloner.cs b/DeepCloner/Cloner.cs new file mode 100644 index 0000000..58076a4 --- /dev/null +++ b/DeepCloner/Cloner.cs @@ -0,0 +1,76 @@ +using Force.DeepCloner.Helpers; + +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 : ICloner + { + 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