Skip to content

Commit 49cac7f

Browse files
CSHARP-2394: Remove dependency on System.Reflection.Emit.
1 parent 4a0fa50 commit 49cac7f

File tree

4 files changed

+194
-14
lines changed

4 files changed

+194
-14
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Please see our [guidelines](CONTRIBUTING.md) for contributing to the driver.
9191
* Bar Arnon https://github.com/I3arnon
9292
* Wan Bachtiar https://github.com/sindbach
9393
* Mark Benvenuto https://github.com/markbenvenuto
94+
* Jimmy Bogard https://github.com/jbogard
9495
* Ross Buggins https://github.com/rbugginsvia
9596
* Ethan Celletti https://github.com/Gekctek
9697
* Bit Diffusion Limited [email protected]

src/MongoDB.Bson/MongoDB.Bson.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
<PackageReference Include="System.Collections.NonGeneric" Version="4.0.1" />
5050
<PackageReference Include="System.Diagnostics.Process" Version="4.1.0" />
5151
<PackageReference Include="System.Dynamic.Runtime" Version="4.0.11" />
52-
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
5352
<PackageReference Include="System.Runtime.Serialization.Formatters" Version="4.3.0" />
5453
</ItemGroup>
5554

src/MongoDB.Bson/Serialization/BsonMemberMap.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using System;
1717
using System.Linq.Expressions;
1818
using System.Reflection;
19-
using System.Reflection.Emit;
2019
using MongoDB.Bson.Serialization.Serializers;
2120

2221
namespace MongoDB.Bson.Serialization
@@ -580,18 +579,14 @@ private Action<object, object> GetFieldSetter()
580579
throw new BsonSerializationException(message);
581580
}
582581

583-
var sourceType = fieldInfo.DeclaringType;
584-
var method = new DynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(object), typeof(object) }, true);
585-
var gen = method.GetILGenerator();
586-
587-
gen.Emit(OpCodes.Ldarg_0);
588-
gen.Emit(OpCodes.Castclass, sourceType);
589-
gen.Emit(OpCodes.Ldarg_1);
590-
gen.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
591-
gen.Emit(OpCodes.Stfld, fieldInfo);
592-
gen.Emit(OpCodes.Ret);
582+
var objParameter = Expression.Parameter(typeof(object), "obj");
583+
var valueParameter = Expression.Parameter(typeof(object), "value");
584+
var field = Expression.Field(Expression.Convert(objParameter, fieldInfo.DeclaringType), fieldInfo);
585+
var value = Expression.Convert(valueParameter, fieldInfo.FieldType);
586+
var body = Expression.Assign(field, value);
593587

594-
return (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
588+
var lambda = Expression.Lambda<Action<object, object>>(body, objParameter, valueParameter);
589+
return lambda.Compile();
595590
}
596591

597592
private Func<object, object> GetGetter()

tests/MongoDB.Bson.Tests/Serialization/Serializers/BsonPrimitiveSerializerTests.cs

Lines changed: 186 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
using System;
1717
using System.Linq;
18-
using MongoDB.Bson;
1918
using MongoDB.Bson.Serialization;
2019
using MongoDB.Bson.Serialization.Attributes;
2120
using Xunit;
@@ -41,6 +40,19 @@ public class TestClass
4140
public bool S;
4241
}
4342

43+
public class TestClassWithPrivate
44+
{
45+
[BsonRepresentation(BsonType.String)]
46+
private bool _b;
47+
48+
public TestClassWithPrivate(bool b)
49+
{
50+
_b = b;
51+
}
52+
53+
public bool GetPrivateB() => _b;
54+
}
55+
4456
[Fact]
4557
public void TestFalse()
4658
{
@@ -72,6 +84,16 @@ public void TestTrue()
7284
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
7385
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
7486
}
87+
88+
[Fact]
89+
public void TestPrivateFieldWithBsonRepresentation()
90+
{
91+
var testValue = true;
92+
var json = $"{{ _b : '{testValue}' }}";
93+
94+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
95+
Assert.Equal(testValue, deserialized.GetPrivateB());
96+
}
7597
}
7698

7799
public class DateTimeSerializerTests
@@ -95,6 +117,19 @@ public class TestClass
95117
public DateTime Document;
96118
}
97119

120+
public class TestClassWithPrivateField
121+
{
122+
[BsonDateTimeOptions(Representation = BsonType.String)]
123+
private DateTime _d;
124+
125+
public TestClassWithPrivateField(DateTime d)
126+
{
127+
_d = d;
128+
}
129+
130+
public DateTime GetPrivateD() => _d;
131+
}
132+
98133
private static string __expectedTemplate =
99134
"{ 'Default' : #Default, 'Local' : #Local, 'Unspecified' : #Unspecified, 'Utc' : #Utc, 'Ticks' : #Ticks, 'String' : '#String', 'DateOnlyString' : '#DateOnlyString', 'Document' : #Document }";
100135

@@ -543,6 +578,16 @@ public void TestUtc()
543578
Assert.Equal(DateTimeKind.Utc, rehydrated.DateOnlyString.Kind);
544579
Assert.Equal(DateTimeKind.Utc, rehydrated.Document.Kind);
545580
}
581+
582+
[Fact]
583+
public void TestPrivateFieldWithBsonRepresentation()
584+
{
585+
var testValue = new DateTime(2020, 01, 01);
586+
var json = $"{{ '_d' : '{testValue:yyyy-MM-ddTHH:mm:ss.FFFZ}' }}";
587+
588+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivateField>(json);
589+
Assert.Equal(testValue, deserialized.GetPrivateD());
590+
}
546591
}
547592

548593
public class DoubleSerializerTests
@@ -558,6 +603,19 @@ public class TestClass
558603
public double S;
559604
}
560605

606+
public class TestClassWithPrivateField
607+
{
608+
[BsonRepresentation(BsonType.String)]
609+
private double _d;
610+
611+
public TestClassWithPrivateField(double d)
612+
{
613+
_d = d;
614+
}
615+
616+
public double GetPrivateD() => _d;
617+
}
618+
561619
[Fact]
562620
public void TestMin()
563621
{
@@ -738,6 +796,16 @@ public void TestPositiveInfinity()
738796
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
739797
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
740798
}
799+
800+
[Fact]
801+
public void TestPrivateFieldWithBsonRepresentation()
802+
{
803+
var testValue = 5;
804+
var json = $"{{ '_d' : '{testValue}' }}";
805+
806+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivateField>(json);
807+
Assert.Equal(testValue, deserialized.GetPrivateD());
808+
}
741809
}
742810

743811
public class GuidSerializerTests
@@ -749,6 +817,19 @@ public class TestClass
749817
public Guid String { get; set; }
750818
}
751819

820+
public class TestClassWithPrivate
821+
{
822+
[BsonRepresentation(BsonType.String)]
823+
private Guid _b;
824+
825+
public TestClassWithPrivate(Guid b)
826+
{
827+
_b = b;
828+
}
829+
830+
public Guid GetPrivateB() => _b;
831+
}
832+
752833
[Fact]
753834
public void TestEmpty()
754835
{
@@ -791,6 +872,16 @@ public void TestGuidRepresentation()
791872
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
792873
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
793874
}
875+
876+
[Fact]
877+
public void TestPrivateFieldWithBsonRepresentation()
878+
{
879+
var testValue = new Guid("01020304-0506-0708-090a-0b0c0d0e0f10");
880+
var json = $"{{ '_b' : '{testValue}' }}";
881+
882+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
883+
Assert.Equal(testValue, deserialized.GetPrivateB());
884+
}
794885
}
795886

796887
public class Int32SerializerTests
@@ -809,6 +900,19 @@ public class TestClass
809900
public int S;
810901
}
811902

903+
public class TestClassWithPrivate
904+
{
905+
[BsonRepresentation(BsonType.String)]
906+
private int _i;
907+
908+
public TestClassWithPrivate(int i)
909+
{
910+
_i = i;
911+
}
912+
913+
public int GetPrivateI() => _i;
914+
}
915+
812916
[Fact]
813917
public void TestMin()
814918
{
@@ -912,6 +1016,16 @@ public void TestMax()
9121016
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
9131017
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
9141018
}
1019+
1020+
[Fact]
1021+
public void TestPrivateFieldWithBsonRepresentation()
1022+
{
1023+
var testValue = 3;
1024+
var json = $"{{ '_i' : '{testValue}' }}";
1025+
1026+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
1027+
Assert.Equal(testValue, deserialized.GetPrivateI());
1028+
}
9151029
}
9161030

9171031
public class Int64SerializerTests
@@ -930,6 +1044,19 @@ public class TestClass
9301044
public long S;
9311045
}
9321046

1047+
public class TestClassWithPrivate
1048+
{
1049+
[BsonRepresentation(BsonType.String)]
1050+
private long _i;
1051+
1052+
public TestClassWithPrivate(long i)
1053+
{
1054+
_i = i;
1055+
}
1056+
1057+
public long GetPrivateI() => _i;
1058+
}
1059+
9331060
[Fact]
9341061
public void TestMin()
9351062
{
@@ -1033,6 +1160,16 @@ public void TestMax()
10331160
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
10341161
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
10351162
}
1163+
1164+
[Fact]
1165+
public void TestPrivateFieldWithBsonRepresentation()
1166+
{
1167+
var testValue = long.MaxValue;
1168+
var json = $"{{ '_i' : '{testValue}' }}";
1169+
1170+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
1171+
Assert.Equal(testValue, deserialized.GetPrivateI());
1172+
}
10361173
}
10371174

10381175
public class ObjectIdSerializerTests
@@ -1044,6 +1181,19 @@ public class TestClass
10441181
public ObjectId String { get; set; }
10451182
}
10461183

1184+
public class TestClassWithPrivate
1185+
{
1186+
[BsonRepresentation(BsonType.String)]
1187+
private ObjectId _o;
1188+
1189+
public TestClassWithPrivate(ObjectId o)
1190+
{
1191+
_o = o;
1192+
}
1193+
1194+
public ObjectId GetPrivateO() => _o;
1195+
}
1196+
10471197
[Fact]
10481198
public void TestSerializer()
10491199
{
@@ -1066,6 +1216,18 @@ public void TestSerializer()
10661216
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
10671217
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
10681218
}
1219+
1220+
[Fact]
1221+
public void TestPrivateFieldWithBsonRepresentation()
1222+
{
1223+
#pragma warning disable 618
1224+
var testValue = new ObjectId(1, 2, 3, 4);
1225+
#pragma warning restore 618
1226+
var json = "{ '_o' : '000000010000020003000004' }";
1227+
1228+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
1229+
Assert.Equal(testValue, deserialized.GetPrivateO());
1230+
}
10691231
}
10701232

10711233
public class StringSerializerTests
@@ -1075,6 +1237,19 @@ public class TestClass
10751237
public String String { get; set; }
10761238
}
10771239

1240+
public class TestClassWithPrivate
1241+
{
1242+
[BsonRepresentation(BsonType.String)]
1243+
private string _s;
1244+
1245+
public TestClassWithPrivate(string s)
1246+
{
1247+
_s = s;
1248+
}
1249+
1250+
public string GetPrivateS() => _s;
1251+
}
1252+
10781253
[Fact]
10791254
public void TestNull()
10801255
{
@@ -1122,5 +1297,15 @@ public void TestHelloWorld()
11221297
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
11231298
Assert.True(bson.SequenceEqual(rehydrated.ToBson()));
11241299
}
1300+
1301+
[Fact]
1302+
public void TestPrivateFieldWithBsonRepresentation()
1303+
{
1304+
var testValue = "test";
1305+
var json = $"{{ '_s' : '{testValue}' }}";
1306+
1307+
var deserialized = BsonSerializer.Deserialize<TestClassWithPrivate>(json);
1308+
Assert.Equal(testValue, deserialized.GetPrivateS());
1309+
}
11251310
}
11261311
}

0 commit comments

Comments
 (0)