Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 882a7c2

Browse files
committed
Remove Reflection.Emit from .NETStd2.0 builds, add to NET45 + NETCORE builds
1 parent be3a106 commit 882a7c2

17 files changed

+969
-1087
lines changed

src/ServiceStack.Text/AutoMappingUtils.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ internal static AssignmentDefinition GetAssignmentDefinition(Type toType, Type f
274274

275275
foreach (var assignmentMember in readMap)
276276
{
277-
AssignmentMember writeMember;
278-
if (writeMap.TryGetValue(assignmentMember.Key, out writeMember))
277+
if (writeMap.TryGetValue(assignmentMember.Key, out var writeMember))
279278
{
280279
definition.AddMatch(assignmentMember.Key, assignmentMember.Value, writeMember);
281280
}

src/ServiceStack.Text/Common/DeserializeKeyValuePair.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public static object ParseKeyValuePair<TKey, TValue>(
7676
valueValue = (TValue)parseValueFn(keyElementValue);
7777
else
7878
throw new SerializationException("Incorrect KeyValuePair property: " + key.ToString());
79+
7980
Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
8081
}
8182

src/ServiceStack.Text/Common/DeserializeType.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,11 @@ public static Type ExtractType(ReadOnlySpan<char> strType)
128128
return null;
129129
}
130130

131-
return PclExport.Instance.UseType(type);
131+
return ReflectionOptimizer.Instance.UseType(type);
132132
}
133133
return null;
134134
}
135135

136-
public static object ParseAbstractType<T>(string value) => ParseAbstractType<T>(value.AsSpan());
137-
138136
public static object ParseAbstractType<T>(ReadOnlySpan<char> value)
139137
{
140138
if (typeof(T).IsAbstract)
@@ -143,7 +141,12 @@ public static object ParseAbstractType<T>(ReadOnlySpan<char> value)
143141
var concreteType = ExtractType(value);
144142
if (concreteType != null)
145143
{
146-
return Serializer.GetParseStringSpanFn(concreteType)(value);
144+
var fn = Serializer.GetParseStringSpanFn(concreteType);
145+
if (fn == ParseAbstractType<T>)
146+
return null;
147+
148+
var ret = fn(value);
149+
return ret;
147150
}
148151
Tracer.Instance.WriteWarning(
149152
"Could not deserialize Abstract Type with unknown concrete type: " + typeof(T).FullName);

src/ServiceStack.Text/Env.cs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ static Env()
1515
throw new ArgumentException("PclExport.Instance needs to be initialized");
1616

1717
var platformName = PclExport.Instance.PlatformName;
18-
if (platformName != PclExport.Platforms.Uwp)
18+
IsUWP = IsRunningAsUwp();
19+
if (!IsUWP)
1920
{
2021
IsMono = AssemblyUtils.FindType("Mono.Runtime") != null;
2122

@@ -37,10 +38,6 @@ static Env()
3738
}
3839
catch (Exception) {}
3940
}
40-
else
41-
{
42-
IsUWP = true;
43-
}
4441

4542
#if NETSTANDARD2_0
4643
IsNetStandard = true;
@@ -50,13 +47,15 @@ static Env()
5047
IsWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows);
5148
IsOSX = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX);
5249

53-
if (!IsIOS && IsOSX && System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.Contains("Mono"))
50+
var fxDesc = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;
51+
if (!IsIOS && IsOSX && fxDesc.Contains("Mono"))
5452
{
5553
var runtimeDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
5654
//iOS detection no longer trustworthy so assuming iOS based on some current heuristics. TODO: improve iOS detection
5755
IsIOS = runtimeDir.StartsWith("/private/var") ||
5856
runtimeDir.Contains("/CoreSimulator/Devices/");
5957
}
58+
IsNetCore = fxDesc.Contains(".NET Core");
6059
}
6160
catch (Exception) {} //throws PlatformNotSupportedException in AWS lambda
6261
IsUnix = IsOSX || IsLinux;
@@ -68,9 +67,17 @@ static Env()
6867
IsLinux = IsUnix;
6968
if (Environment.GetEnvironmentVariable("OS")?.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) >= 0)
7069
IsWindows = true;
70+
#elif NETCORE2_1
71+
IsNetCore = true;
7172
#endif
73+
7274
SupportsExpressions = !IsIOS;
73-
SupportsEmit = !IsIOS;
75+
SupportsEmit = !IsIOS && !IsUWP;
76+
77+
if (IsUWP || IsIOS)
78+
{
79+
ReflectionOptimizer.Instance = ExpressionReflectionOptimizer.Provider;
80+
}
7481

7582
ServerUserAgent = "ServiceStack/" +
7683
ServiceStackVersion + " "
@@ -80,9 +87,6 @@ static Env()
8087
VersionString = ServiceStackVersion.ToString(CultureInfo.InvariantCulture);
8188

8289
__releaseDate = new DateTime(2001,01,01);
83-
84-
PclExport.Instance.SupportsEmit = SupportsEmit;
85-
PclExport.Instance.SupportsExpression = SupportsExpressions;
8690
}
8791

8892
public static string VersionString { get; set; }
@@ -109,9 +113,11 @@ static Env()
109113

110114
public static bool IsNetFramework { get; set; }
111115

112-
public static bool SupportsExpressions { get; set; }
116+
public static bool IsNetCore { get; set; }
117+
118+
public static bool SupportsExpressions { get; private set; }
113119

114-
public static bool SupportsEmit { get; set; }
120+
public static bool SupportsEmit { get; private set; }
115121

116122
public static bool StrictMode { get; set; }
117123

@@ -167,5 +173,39 @@ public static string ReferenceAssembyPath
167173
}
168174
set => referenceAssembyPath = value;
169175
}
176+
177+
//https://blogs.msdn.microsoft.com/appconsult/2016/11/03/desktop-bridge-identify-the-applications-context/
178+
//https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs
179+
const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
180+
181+
[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true)]
182+
static extern int GetCurrentPackageFullName(ref int packageFullNameLength, System.Text.StringBuilder packageFullName);
183+
184+
private static bool IsRunningAsUwp()
185+
{
186+
if (IsWindows7OrLower)
187+
return false;
188+
189+
int length = 0;
190+
var sb = new System.Text.StringBuilder(0);
191+
int result = GetCurrentPackageFullName(ref length, sb);
192+
193+
sb = new System.Text.StringBuilder(length);
194+
result = GetCurrentPackageFullName(ref length, sb);
195+
196+
return result != APPMODEL_ERROR_NO_PACKAGE;
197+
}
198+
199+
private static bool IsWindows7OrLower
200+
{
201+
get
202+
{
203+
int versionMajor = Environment.OSVersion.Version.Major;
204+
int versionMinor = Environment.OSVersion.Version.Minor;
205+
double version = versionMajor + (double)versionMinor / 10;
206+
return version <= 6.1;
207+
}
208+
}
209+
170210
}
171211
}

src/ServiceStack.Text/Pcl.Dynamic.cs

Lines changed: 1 addition & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//Copyright (c) ServiceStack, Inc. All Rights Reserved.
22
//License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
33

4-
#if !(PCL || LITE || NO_DYNAMIC)
4+
#if NET45 || NETCORE2_1
55

66
using System;
77
using System.Collections.Generic;
@@ -10,12 +10,9 @@
1010
using ServiceStack.Text.Common;
1111
using ServiceStack.Text.Json;
1212
using System.Linq;
13-
using System.Text;
1413

15-
#if !(__IOS__)
1614
using System.Reflection;
1715
using System.Reflection.Emit;
18-
#endif
1916

2017
namespace ServiceStack
2118
{
@@ -188,157 +185,5 @@ internal static string Underscored(IEnumerable<char> pascalCase)
188185
}
189186
}
190187

191-
#if !(__IOS__)
192-
public static class DynamicProxy
193-
{
194-
public static T GetInstanceFor<T>()
195-
{
196-
return (T)GetInstanceFor(typeof(T));
197-
}
198-
199-
static readonly ModuleBuilder ModuleBuilder;
200-
static readonly AssemblyBuilder DynamicAssembly;
201-
static readonly Type[] EmptyTypes = new Type[0];
202-
203-
public static object GetInstanceFor(Type targetType)
204-
{
205-
lock (DynamicAssembly)
206-
{
207-
var constructedType = DynamicAssembly.GetType(ProxyName(targetType)) ?? GetConstructedType(targetType);
208-
var instance = Activator.CreateInstance(constructedType);
209-
return instance;
210-
}
211-
}
212-
213-
static string ProxyName(Type targetType)
214-
{
215-
return targetType.Name + "Proxy";
216-
}
217-
218-
static DynamicProxy()
219-
{
220-
var assemblyName = new AssemblyName("DynImpl");
221-
#if NETSTANDARD2_0
222-
DynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
223-
#else
224-
DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
225-
#endif
226-
ModuleBuilder = DynamicAssembly.DefineDynamicModule("DynImplModule");
227-
}
228-
229-
static Type GetConstructedType(Type targetType)
230-
{
231-
var typeBuilder = ModuleBuilder.DefineType(targetType.Name + "Proxy", TypeAttributes.Public);
232-
233-
var ctorBuilder = typeBuilder.DefineConstructor(
234-
MethodAttributes.Public,
235-
CallingConventions.Standard,
236-
new Type[] { });
237-
var ilGenerator = ctorBuilder.GetILGenerator();
238-
ilGenerator.Emit(OpCodes.Ret);
239-
240-
IncludeType(targetType, typeBuilder);
241-
242-
foreach (var face in targetType.GetInterfaces())
243-
IncludeType(face, typeBuilder);
244-
245-
#if NETSTANDARD2_0
246-
return typeBuilder.CreateTypeInfo().AsType();
247-
#else
248-
return typeBuilder.CreateType();
249-
#endif
250-
}
251-
252-
static void IncludeType(Type typeOfT, TypeBuilder typeBuilder)
253-
{
254-
var methodInfos = typeOfT.GetMethods();
255-
foreach (var methodInfo in methodInfos)
256-
{
257-
if (methodInfo.Name.StartsWith("set_", StringComparison.Ordinal)) continue; // we always add a set for a get.
258-
259-
if (methodInfo.Name.StartsWith("get_", StringComparison.Ordinal))
260-
{
261-
BindProperty(typeBuilder, methodInfo);
262-
}
263-
else
264-
{
265-
BindMethod(typeBuilder, methodInfo);
266-
}
267-
}
268-
269-
typeBuilder.AddInterfaceImplementation(typeOfT);
270-
}
271-
272-
static void BindMethod(TypeBuilder typeBuilder, MethodInfo methodInfo)
273-
{
274-
var methodBuilder = typeBuilder.DefineMethod(
275-
methodInfo.Name,
276-
MethodAttributes.Public | MethodAttributes.Virtual,
277-
methodInfo.ReturnType,
278-
methodInfo.GetParameters().Select(p => p.GetType()).ToArray()
279-
);
280-
var methodILGen = methodBuilder.GetILGenerator();
281-
if (methodInfo.ReturnType == typeof(void))
282-
{
283-
methodILGen.Emit(OpCodes.Ret);
284-
}
285-
else
286-
{
287-
if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum)
288-
{
289-
MethodInfo getMethod = typeof(Activator).GetMethod("CreateInstance", new[] { typeof(Type) });
290-
LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType);
291-
methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType);
292-
methodILGen.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
293-
methodILGen.Emit(OpCodes.Callvirt, getMethod);
294-
methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType);
295-
}
296-
else
297-
{
298-
methodILGen.Emit(OpCodes.Ldnull);
299-
}
300-
methodILGen.Emit(OpCodes.Ret);
301-
}
302-
typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
303-
}
304-
305-
public static void BindProperty(TypeBuilder typeBuilder, MethodInfo methodInfo)
306-
{
307-
// Backing Field
308-
string propertyName = methodInfo.Name.Replace("get_", "");
309-
Type propertyType = methodInfo.ReturnType;
310-
FieldBuilder backingField = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
311-
312-
//Getter
313-
MethodBuilder backingGet = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public |
314-
MethodAttributes.SpecialName | MethodAttributes.Virtual |
315-
MethodAttributes.HideBySig, propertyType, EmptyTypes);
316-
ILGenerator getIl = backingGet.GetILGenerator();
317-
318-
getIl.Emit(OpCodes.Ldarg_0);
319-
getIl.Emit(OpCodes.Ldfld, backingField);
320-
getIl.Emit(OpCodes.Ret);
321-
322-
323-
//Setter
324-
MethodBuilder backingSet = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public |
325-
MethodAttributes.SpecialName | MethodAttributes.Virtual |
326-
MethodAttributes.HideBySig, null, new[] { propertyType });
327-
328-
ILGenerator setIl = backingSet.GetILGenerator();
329-
330-
setIl.Emit(OpCodes.Ldarg_0);
331-
setIl.Emit(OpCodes.Ldarg_1);
332-
setIl.Emit(OpCodes.Stfld, backingField);
333-
setIl.Emit(OpCodes.Ret);
334-
335-
// Property
336-
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
337-
propertyBuilder.SetGetMethod(backingGet);
338-
propertyBuilder.SetSetMethod(backingSet);
339-
}
340-
}
341-
#endif
342-
343188
}
344189
#endif

0 commit comments

Comments
 (0)