Skip to content

Commit 2aee0be

Browse files
authored
Fix exception in DynamicClassFactory.CreateType when using Blazor WebAssembly (#518)
1 parent dbd6a7f commit 2aee0be

File tree

10 files changed

+126
-43
lines changed

10 files changed

+126
-43
lines changed
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
22
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EF/@EntryIndexedValue">EF</s:String>
3-
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UTC/@EntryIndexedValue">UTC</s:String></wpf:ResourceDictionary>
3+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UTC/@EntryIndexedValue">UTC</s:String>
4+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WASM/@EntryIndexedValue">WASM</s:String></wpf:ResourceDictionary>

src-blazor/BlazorAppTest/Pages/Index.razor

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ else
5959

6060
protected override async Task OnInitializedAsync()
6161
{
62+
Console.WriteLine("is blazor wasm" + (Type.GetType("Mono.Runtime") != null));
63+
6264
forecasts = await Http.GetJsonAsync<WeatherForecast[]>("sample-data/weather.json");
6365
}
6466

Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1-
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
2-
3-
<PropertyGroup>
4-
<TargetFramework>net5.0</TargetFramework>
5-
</PropertyGroup>
6-
7-
<ItemGroup>
8-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.5" />
9-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.5" PrivateAssets="all" />
10-
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.9" />
11-
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
12-
</ItemGroup>
1+
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
6+
<!--<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>-->
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.7" />
11+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.7" PrivateAssets="all" />
12+
<!--<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.9" />-->
13+
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\src\System.Linq.Dynamic.Core\System.Linq.Dynamic.Core.csproj" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<PackageReference Include="JetBrains.Annotations" Version="2020.3.0" PrivateAssets="All" />
22+
</ItemGroup>
1323

1424
</Project>

src-blazor/BlazorWASMExample/Pages/Counter.razor

+41
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
@page "/counter"
2+
@using System.Linq.Dynamic.Core
3+
@using System.Reflection.Emit
4+
@using System.Reflection
5+
@using Microsoft.AspNetCore.Components.WebAssembly.Infrastructure
26

37
<h1>Counter</h1>
48

@@ -7,10 +11,47 @@
711
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
812

913
@code {
14+
private static string DynamicAssemblyName = "System.Linq.Dynamic.Core.DynamicClasses, Version=1.0.0.0";
15+
private static string DynamicModuleName = "System.Linq.Dynamic.Core.DynamicClasses";
16+
1017
private int currentCount = 0;
1118

1219
private void IncrementCount()
1320
{
1421
currentCount++;
22+
23+
var dynamicProperties = new List<DynamicProperty>();
24+
dynamicProperties.Add(new DynamicProperty("Name", typeof(string)));
25+
dynamicProperties.Add(new DynamicProperty("Age", typeof(int)));
26+
27+
try
28+
{
29+
Console.WriteLine("FrameworkDescription " + System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
30+
Console.WriteLine("OSArchitecture " + System.Runtime.InteropServices.RuntimeInformation.OSArchitecture);
31+
Console.WriteLine("OSDescription " + System.Runtime.InteropServices.RuntimeInformation.OSDescription);
32+
Console.WriteLine("ProcessArchitecture " + System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture);
33+
Console.WriteLine("RuntimeIdentifier " + System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier);
34+
35+
Console.WriteLine("is blazor wasm" + (Type.GetType("Mono.Runtime") != null));
36+
37+
var c = System.Runtime.InteropServices.OSPlatform.Create("BROWSER");
38+
Console.WriteLine(c);
39+
40+
var i = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(c);
41+
Console.WriteLine(i);
42+
43+
var model = DynamicClassFactory.CreateType(dynamicProperties);
44+
45+
Console.WriteLine(model.GetType());
46+
47+
foreach (var p in model.GetProperties())
48+
{
49+
Console.WriteLine(p.Name + " - " + p.PropertyType);
50+
}
51+
}
52+
catch (Exception exception)
53+
{
54+
throw;
55+
}
1556
}
1657
}

src/System.Linq.Dynamic.Core/Compatibility/CustomTypeBuilderExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public static Type CreateType(this TypeBuilder tb)
1212
}
1313
#endif
1414

15-
#if NET35 || NET40 || SILVERLIGHT || WPSL || NETCOREAPP
15+
#if NET35 || NET40 || SILVERLIGHT || WPSL || NETCOREAPP || NETSTANDARD2_1
1616
public static PropertyBuilder DefineProperty(this TypeBuilder tb, string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
1717
{
1818
return tb.DefineProperty(name, attributes, returnType, parameterTypes);

src/System.Linq.Dynamic.Core/DynamicClassFactory.cs

+32-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
44
using System.Diagnostics;
5+
using System.Linq.Dynamic.Core.Util;
56
using System.Linq.Dynamic.Core.Validation;
67
using System.Reflection;
78
using System.Reflection.Emit;
@@ -223,33 +224,37 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties, bool
223224

224225
for (int i = 0; i < names.Length; i++)
225226
{
226-
Type equalityComparerT = EqualityComparer.MakeGenericType(generics[i].AsType());
227-
228-
// Equals()
229-
MethodInfo equalityComparerTDefault = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerDefault);
230-
MethodInfo equalityComparerTEquals = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerEquals);
231-
232-
// Illegal one-byte branch at position: 9. Requested branch was: 143.
233-
// So replace OpCodes.Brfalse_S to OpCodes.Brfalse
234-
ilgeneratorEquals.Emit(OpCodes.Brfalse, equalsLabel);
235-
ilgeneratorEquals.Emit(OpCodes.Call, equalityComparerTDefault);
236-
ilgeneratorEquals.Emit(OpCodes.Ldarg_0);
237-
ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
238-
ilgeneratorEquals.Emit(OpCodes.Ldloc_0);
239-
ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
240-
ilgeneratorEquals.Emit(OpCodes.Callvirt, equalityComparerTEquals);
241-
242-
// GetHashCode();
243-
MethodInfo equalityComparerTGetHashCode = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerGetHashCode);
244-
ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0);
245-
ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, -1521134295);
246-
ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0);
247-
ilgeneratorGetHashCode.Emit(OpCodes.Mul);
248-
ilgeneratorGetHashCode.Emit(OpCodes.Call, equalityComparerTDefault);
249-
ilgeneratorGetHashCode.Emit(OpCodes.Ldarg_0);
250-
ilgeneratorGetHashCode.Emit(OpCodes.Ldfld, fields[i]);
251-
ilgeneratorGetHashCode.Emit(OpCodes.Callvirt, equalityComparerTGetHashCode);
252-
ilgeneratorGetHashCode.Emit(OpCodes.Add);
227+
// https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/516
228+
if (!RuntimeInformationUtils.IsBlazorWASM)
229+
{
230+
Type equalityComparerT = EqualityComparer.MakeGenericType(generics[i].AsType());
231+
232+
// Equals()
233+
MethodInfo equalityComparerTDefault = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerDefault);
234+
MethodInfo equalityComparerTEquals = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerEquals);
235+
236+
// Illegal one-byte branch at position: 9. Requested branch was: 143.
237+
// So replace OpCodes.Brfalse_S to OpCodes.Brfalse
238+
ilgeneratorEquals.Emit(OpCodes.Brfalse, equalsLabel);
239+
ilgeneratorEquals.Emit(OpCodes.Call, equalityComparerTDefault);
240+
ilgeneratorEquals.Emit(OpCodes.Ldarg_0);
241+
ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
242+
ilgeneratorEquals.Emit(OpCodes.Ldloc_0);
243+
ilgeneratorEquals.Emit(OpCodes.Ldfld, fields[i]);
244+
ilgeneratorEquals.Emit(OpCodes.Callvirt, equalityComparerTEquals);
245+
246+
// GetHashCode();
247+
MethodInfo equalityComparerTGetHashCode = TypeBuilder.GetMethod(equalityComparerT, EqualityComparerGetHashCode);
248+
ilgeneratorGetHashCode.Emit(OpCodes.Stloc_0);
249+
ilgeneratorGetHashCode.Emit(OpCodes.Ldc_I4, -1521134295);
250+
ilgeneratorGetHashCode.Emit(OpCodes.Ldloc_0);
251+
ilgeneratorGetHashCode.Emit(OpCodes.Mul);
252+
ilgeneratorGetHashCode.Emit(OpCodes.Call, equalityComparerTDefault);
253+
ilgeneratorGetHashCode.Emit(OpCodes.Ldarg_0);
254+
ilgeneratorGetHashCode.Emit(OpCodes.Ldfld, fields[i]);
255+
ilgeneratorGetHashCode.Emit(OpCodes.Callvirt, equalityComparerTGetHashCode);
256+
ilgeneratorGetHashCode.Emit(OpCodes.Add);
257+
}
253258

254259
// ToString();
255260
ilgeneratorToString.Emit(OpCodes.Ldloc_0);

src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Description>This is a .NETStandard / .NET Core port of the the Microsoft assembly for the .Net 4.0 Dynamic language functionality.</Description>
77
<AssemblyTitle>System.Linq.Dynamic.Core</AssemblyTitle>
88
<Authors>ZZZ Projects;Stef Heyenrath;Microsoft;Scott Guthrie;King Wilder;Nathan Arnott</Authors>
9-
<TargetFrameworks>net35;net40;net45;net46;netstandard1.3;netstandard2.0;uap10.0;netcoreapp2.1</TargetFrameworks>
9+
<TargetFrameworks>net35;net40;net45;net46;netstandard1.3;netstandard2.0;netstandard2.1;uap10.0;netcoreapp2.1;net5.0</TargetFrameworks>
1010
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1111
<AssemblyName>System.Linq.Dynamic.Core</AssemblyName>
1212
<AssemblyOriginatorKeyFile>System.Linq.Dynamic.Core.snk</AssemblyOriginatorKeyFile>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace System.Linq.Dynamic.Core.Util
2+
{
3+
internal static class RuntimeInformationUtils
4+
{
5+
public static bool IsBlazorWASM;
6+
7+
static RuntimeInformationUtils()
8+
{
9+
#if NET35 || NET40 || NET45 || NET46 || UAP10_0
10+
IsBlazorWASM = false;
11+
#else
12+
IsBlazorWASM =
13+
// Used for Blazor WebAssembly .NET Core 3.x / .NET Standard 2.x
14+
Type.GetType("Mono.Runtime") != null ||
15+
16+
// Use for Blazor WebAssembly .NET
17+
// See also https://github.com/mono/mono/pull/19568/files
18+
Runtime.InteropServices.RuntimeInformation.IsOSPlatform(Runtime.InteropServices.OSPlatform.Create("BROWSER"));
19+
#endif
20+
}
21+
}
22+
}

test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
</PackageReference>
2323
<PackageReference Include="FluentAssertions" Version="5.10.3" />
2424
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
25+
<PackageReference Include="Mono.Reflection" Version="2.0.0" />
2526
<PackageReference Include="OpenCover" Version="4.7.922" />
2627
<PackageReference Include="ReportGenerator" Version="4.5.4" />
28+
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
2729
<PackageReference Include="xunit.runner.console" Version="2.4.1">
2830
<PrivateAssets>all</PrivateAssets>
2931
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

version.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
22
<PropertyGroup>
3-
<PatchVersion>10</PatchVersion>
3+
<PatchVersion>11-preview-01</PatchVersion>
44
</PropertyGroup>
55
</Project>

0 commit comments

Comments
 (0)