Skip to content

Commit d94fac1

Browse files
committed
Merge branch 'feature/anotherCloningVariant' into develop
2 parents f0cd989 + 9ad9417 commit d94fac1

24 files changed

+472
-122
lines changed

DeepCloner.Tests/ArraysSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55

66
namespace Force.DeepCloner.Tests
77
{
8-
[TestFixture]
9-
public class ArraysSpec
8+
[TestFixture(false)]
9+
[TestFixture(true)]
10+
public class ArraysSpec : BaseTest
1011
{
12+
public ArraysSpec(object isSafeInit)
13+
: base((bool)isSafeInit)
14+
{
15+
}
16+
1117
[Test]
1218
public void IntArray_Should_Be_Cloned()
1319
{

DeepCloner.Tests/BaseTest.cs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Reflection;
2+
3+
using Force.DeepCloner.Helpers;
4+
5+
namespace Force.DeepCloner.Tests
6+
{
7+
public class BaseTest
8+
{
9+
public BaseTest(bool isSafeInit)
10+
{
11+
SwitchTo(isSafeInit);
12+
}
13+
14+
public static void SwitchTo(bool isSafeInit)
15+
{
16+
typeof(ShallowObjectCloner).GetMethod("SwitchTo", BindingFlags.NonPublic | BindingFlags.Static)
17+
.Invoke(null, new object[] { isSafeInit });
18+
}
19+
}
20+
}

DeepCloner.Tests/CloneExtensionsSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
namespace Force.DeepCloner.Tests
66
{
7-
[TestFixture]
8-
public class CloneExtensionsSpec
7+
[TestFixture(false)]
8+
[TestFixture(true)]
9+
public class CloneExtensionsSpec : BaseTest
910
{
11+
public CloneExtensionsSpec(bool isSafeInit)
12+
: base(isSafeInit)
13+
{
14+
}
15+
1016
public class C1
1117
{
1218
public int X { get; set; }

DeepCloner.Tests/ConstructorsSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
namespace Force.DeepCloner.Tests
66
{
7-
[TestFixture]
8-
public class ConstructorsSpec
7+
[TestFixture(false)]
8+
[TestFixture(true)]
9+
public class ConstructorsSpec : BaseTest
910
{
11+
public ConstructorsSpec(bool isSafeInit)
12+
: base(isSafeInit)
13+
{
14+
}
15+
1016
public class T1
1117
{
1218
private T1()

DeepCloner.Tests/DeepCloner.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
</ItemGroup>
5050
<ItemGroup>
5151
<Compile Include="ArraysSpec.cs" />
52+
<Compile Include="BaseTest.cs" />
5253
<Compile Include="CloneExtensionsSpec.cs" />
5354
<Compile Include="ConstructorsSpec.cs" />
5455
<Compile Include="GenericsSpec.cs" />

DeepCloner.Tests/GenericsSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
namespace Force.DeepCloner.Tests
66
{
7-
[TestFixture]
8-
public class GenericsSpec
7+
[TestFixture(false)]
8+
[TestFixture(true)]
9+
public class GenericsSpec : BaseTest
910
{
11+
public GenericsSpec(bool isSafeInit)
12+
: base(isSafeInit)
13+
{
14+
}
15+
1016
[Test]
1117
public void Tuple_Should_Be_Cloned()
1218
{

DeepCloner.Tests/InheritanceSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55

66
namespace Force.DeepCloner.Tests
77
{
8-
[TestFixture]
9-
public class InheritanceSpec
8+
[TestFixture(false)]
9+
[TestFixture(true)]
10+
public class InheritanceSpec : BaseTest
1011
{
12+
public InheritanceSpec(bool isSafeInit)
13+
: base(isSafeInit)
14+
{
15+
}
16+
1117
public class C1 : IDisposable
1218
{
1319
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]

DeepCloner.Tests/LoopCheckSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
namespace Force.DeepCloner.Tests
44
{
5-
[TestFixture]
6-
public class LoopCheckSpec
5+
[TestFixture(false)]
6+
[TestFixture(true)]
7+
public class LoopCheckSpec : BaseTest
78
{
9+
public LoopCheckSpec(bool isSafeInit)
10+
: base(isSafeInit)
11+
{
12+
}
13+
814
public class C1
915
{
1016
public int F { get; set; }

DeepCloner.Tests/PerformanceSpec.cs

+17-3
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ private T CloneViaFormatter<T>(T obj)
5959
}
6060

6161
[Test, Ignore("Manual")]
62-
public void Test_Construct_Variants()
62+
[TestCase(false)]
63+
[TestCase(true)]
64+
public void Test_Construct_Variants(bool isSafe)
6365
{
66+
// we cache cloners for type, so, this only variant with separate run
67+
BaseTest.SwitchTo(isSafe);
6468
var c1 = new C1 { V1 = 1 };
6569
// warm up
6670
for (var i = 0; i < 1000; i++) ManualDeepClone(c1);
@@ -137,6 +141,9 @@ public void Test_Shallow_Variants()
137141
// warm up
138142
for (var i = 0; i < 1000; i++) ManualShallowClone(c1);
139143
for (var i = 0; i < 1000; i++) c1.Clone();
144+
BaseTest.SwitchTo(false);
145+
for (var i = 0; i < 1000; i++) c1.ShallowClone();
146+
BaseTest.SwitchTo(true);
140147
for (var i = 0; i < 1000; i++) c1.ShallowClone();
141148
for (var i = 0; i < 1000; i++) c1.GetClone();
142149

@@ -150,10 +157,17 @@ public void Test_Shallow_Variants()
150157

151158
for (var i = 0; i < 1000000; i++) c1.Clone();
152159
Console.WriteLine("Auto Internal: " + sw.ElapsedMilliseconds);
153-
sw.Restart();
160+
sw.Reset();
161+
BaseTest.SwitchTo(false);
162+
sw.Start();
163+
for (var i = 0; i < 1000000; i++) c1.ShallowClone();
164+
Console.WriteLine("Shallow Unsafe: " + sw.ElapsedMilliseconds);
165+
sw.Reset();
154166

167+
BaseTest.SwitchTo(true);
168+
sw.Start();
155169
for (var i = 0; i < 1000000; i++) c1.ShallowClone();
156-
Console.WriteLine("Shallow: " + sw.ElapsedMilliseconds);
170+
Console.WriteLine("Shallow Safe: " + sw.ElapsedMilliseconds);
157171
sw.Restart();
158172

159173
for (var i = 0; i < 1000000; i++) c1.GetClone(CloningFlags.Shallow);

DeepCloner.Tests/PermissionSpec.cs

+9-4
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@ public void EnsurePermission()
2525
// assembly execute
2626
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
2727

28-
permissions.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
29-
30-
permissions.AddPermission(new SecurityPermission(PermissionState.Unrestricted));
28+
permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess | ReflectionPermissionFlag.MemberAccess));
29+
// permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
3130

3231
var test = AppDomain.CreateDomain("sandbox", null, setup, permissions);
3332

3433
var instance = (Executor)test.CreateInstanceFromAndUnwrap(this.GetType().Assembly.Location, typeof(Executor).FullName);
3534
instance.DoShallowClone();
35+
instance.DoDeepClone();
36+
}
37+
38+
public class Test
39+
{
40+
public int X { get; set; }
3641
}
3742

3843
public class Executor : MarshalByRefObject
@@ -44,7 +49,7 @@ public void DoDeepClone()
4449

4550
public void DoShallowClone()
4651
{
47-
new List<int> { 1, 2, 3 }.ShallowClone();
52+
new List<int> { 1, 2, 3 }.ShallowClone();
4853
}
4954
}
5055
}

DeepCloner.Tests/ShallowClonerSpec.cs

+18-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66

77
namespace Force.DeepCloner.Tests
88
{
9-
[TestFixture]
10-
public class ShallowClonerSpec
9+
[TestFixture(false)]
10+
[TestFixture(true)]
11+
public class ShallowClonerSpec : BaseTest
1112
{
13+
public ShallowClonerSpec(bool isSafeInit)
14+
: base(isSafeInit)
15+
{
16+
}
17+
1218
[Test]
1319
public void SimpleObject_Should_Be_Cloned()
1420
{
@@ -94,5 +100,15 @@ public void Primitive_Should_Be_Cloned()
94100
Assert.That(((object)null).ShallowClone(), Is.Null);
95101
Assert.That(3.ShallowClone(), Is.EqualTo(3));
96102
}
103+
104+
[Test]
105+
public void Array_Should_Be_Cloned()
106+
{
107+
var a = new[] { 3, 4 };
108+
var clone = a.ShallowClone();
109+
Assert.That(clone.Length, Is.EqualTo(2));
110+
Assert.That(clone[0], Is.EqualTo(3));
111+
Assert.That(clone[1], Is.EqualTo(4));
112+
}
97113
}
98114
}

DeepCloner.Tests/SimpleObjectSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77

88
namespace Force.DeepCloner.Tests
99
{
10-
[TestFixture]
11-
public class SimpleObjectSpec
10+
[TestFixture(true)]
11+
[TestFixture(false)]
12+
public class SimpleObjectSpec : BaseTest
1213
{
14+
public SimpleObjectSpec(bool isSafeInit)
15+
: base(isSafeInit)
16+
{
17+
}
18+
1319
[Test]
1420
public void SimpleObject_Should_Be_Cloned()
1521
{

DeepCloner.Tests/StandardTypesSpec.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99

1010
namespace Force.DeepCloner.Tests
1111
{
12-
[TestFixture]
13-
public class StandardTypesSpec
12+
[TestFixture(false)]
13+
[TestFixture(true)]
14+
public class StandardTypesSpec : BaseTest
1415
{
16+
public StandardTypesSpec(bool isSafeInit)
17+
: base(isSafeInit)
18+
{
19+
}
20+
1521
[Test]
1622
public void StandardTypes_Should_Be_Cloned()
1723
{

DeepCloner.nuspec

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<metadata>
44
<id>DeepCloner</id>
55
<title>DeepCloner</title>
6-
<version>0.8.2</version>
6+
<version>0.9.0</version>
77
<authors>force</authors>
88
<owners>force</owners>
99
<licenseUrl>https://github.com/force-net/DeepCloner/blob/develop/LICENSE</licenseUrl>
@@ -14,6 +14,7 @@
1414
<releaseNotes>
1515
Fixed an issue with handling references to arrays
1616
Added support for multidimensional arrays and non-zero-based arrays
17+
Added fallback for non-fulltrust code through expressions
1718
</releaseNotes>
1819
<copyright>Copyright by Force 2016</copyright>
1920
<tags>.NET shallow deep clone</tags>

DeepCloner/DeepCloner.csproj

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<DocumentationFile>bin\Release\DeepCloner.xml</DocumentationFile>
3232
</PropertyGroup>
3333
<PropertyGroup>
34-
<SignAssembly>true</SignAssembly>
34+
<SignAssembly>false</SignAssembly>
3535
</PropertyGroup>
3636
<PropertyGroup>
3737
<DelaySign>true</DelaySign>
@@ -50,13 +50,14 @@
5050
</ItemGroup>
5151
<ItemGroup>
5252
<Compile Include="DeepClonerExtensions.cs" />
53+
<Compile Include="Helpers\DeepClonerExprGenerator.cs" />
5354
<Compile Include="Helpers\DeepClonerCache.cs" />
5455
<Compile Include="Helpers\DeepClonerGenerator.cs" />
5556
<Compile Include="Helpers\DeepClonerMsilGenerator.cs" />
5657
<Compile Include="Helpers\DeepClonerSafeTypes.cs" />
5758
<Compile Include="Helpers\DeepCloneState.cs" />
5859
<Compile Include="Helpers\ShallowClonerGenerator.cs" />
59-
<Compile Include="Helpers\ShallowSafeObjectCloner.cs" />
60+
<Compile Include="Helpers\ShallowObjectCloner.cs" />
6061
<Compile Include="Helpers\TypeCreationHelper.cs" />
6162
<Compile Include="Properties\AssemblyInfo.cs" />
6263
</ItemGroup>

DeepCloner/DeepClonerExtensions.cs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Security;
1+
using System;
2+
using System.Security;
23

34
using Force.DeepCloner.Helpers;
45

@@ -12,7 +13,6 @@ public static class DeepClonerExtensions
1213
/// <summary>
1314
/// Performs deep (full) copy of object and related graph
1415
/// </summary>
15-
// [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] // <-- this attribute slowers execution
1616
public static T DeepClone<T>(this T obj)
1717
{
1818
return DeepClonerGenerator.CloneObject(obj);
@@ -21,7 +21,6 @@ public static T DeepClone<T>(this T obj)
2121
/// <summary>
2222
/// Performs shallow (only new object returned, without cloning of dependencies) copy of object
2323
/// </summary>
24-
// [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] // <-- this attribute slowers execution
2524
public static T ShallowClone<T>(this T obj)
2625
{
2726
return ShallowClonerGenerator.CloneObject(obj);
@@ -31,7 +30,7 @@ static DeepClonerExtensions()
3130
{
3231
if (!PermissionCheck())
3332
{
34-
throw new SecurityException("DeepCloner should have enough permissions to run. FullTrust set is enough to run.");
33+
throw new SecurityException("DeepCloner should have enough permissions to run. Grant FullTrust or Reflection permission.");
3534
}
3635
}
3736

@@ -47,6 +46,10 @@ private static bool PermissionCheck()
4746
{
4847
return false;
4948
}
49+
catch (MemberAccessException)
50+
{
51+
return false;
52+
}
5053

5154
return true;
5255
}

0 commit comments

Comments
 (0)