Skip to content

Commit de25411

Browse files
authored
(#149) Update all packages to 8.x latest. (#151)
* (#149) Updated all packages to latest 8.x * (#149) Fixed .NET 9 synchronization context bug from .NET 9 performance improvements
1 parent 8d2a9e9 commit de25411

File tree

31 files changed

+457
-140
lines changed

31 files changed

+457
-140
lines changed

Datasync.Toolkit.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ EndProject
1111
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D59F1489-5D74-4F52-B78B-88037EAB2838}"
1212
ProjectSection(SolutionItems) = preProject
1313
tests\Directory.Build.props = tests\Directory.Build.props
14-
tests\EFCore.Packages.props = tests\EFCore.Packages.props
1514
EndProjectSection
1615
EndProject
1716
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.Server.Abstractions", "src\CommunityToolkit.Datasync.Server.Abstractions\CommunityToolkit.Datasync.Server.Abstractions.csproj", "{852F8266-603E-4FC6-A5CB-E492E747924F}"
@@ -44,6 +43,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Datasync.T
4443
EndProject
4544
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{2D2A6EFC-015D-4258-96D4-24C78F8C59F9}"
4645
ProjectSection(SolutionItems) = preProject
46+
Directory.Packages.props = Directory.Packages.props
4747
.github\workflows\SignedPackageFileList.txt = .github\workflows\SignedPackageFileList.txt
4848
.github\workflows\SignedTemplateFileList.txt = .github\workflows\SignedTemplateFileList.txt
4949
EndProjectSection

Directory.Packages.props

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,37 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
55
</PropertyGroup>
6-
76
<ItemGroup>
8-
<PackageVersion Include="AutoMapper" Version="12.0.1" />
9-
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
10-
<PackageVersion Include="FluentAssertions.Web" Version="1.2.5" />
11-
<PackageVersion Include="LiteDB" Version="5.0.17" />
12-
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.3" />
13-
<PackageVersion Include="Microsoft.AspNetCore.OData" Version="8.2.5" />
14-
<PackageVersion Include="Microsoft.Azure.Core.Spatial" Version="1.1.0" />
15-
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
16-
<PackageVersion Include="Microsoft.EntityFrameworkCore.Cosmos" Version="8.0.7" />
17-
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.7" />
18-
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.7" />
19-
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.7" />
20-
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
21-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
22-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
7+
<PackageVersion Include="AutoMapper" Version="13.0.1" />
8+
<PackageVersion Include="Azure.Identity" Version="1.13.1" />
9+
<PackageVersion Include="FluentAssertions" Version="6.12.2" />
10+
<PackageVersion Include="FluentAssertions.Web" Version="1.5.0" />
11+
<PackageVersion Include="LiteDB" Version="5.0.21" />
12+
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.11" />
13+
<PackageVersion Include="Microsoft.AspNetCore.OData" Version="9.1.0" />
14+
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
15+
<PackageVersion Include="Microsoft.EntityFrameworkCore.Cosmos" Version="8.0.11" />
16+
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.11" />
17+
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
18+
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
19+
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
20+
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" />
21+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
22+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
2323
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
24-
<PackageVersion Include="Microsoft.Spatial" Version="7.20.0" />
25-
<PackageVersion Include="NSubstitute" Version="5.1.0" />
26-
<PackageVersion Include="NSwag.AspNetCore" Version="14.0.8" />
27-
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
28-
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.6.2" />
29-
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="8.0.1" />
24+
<PackageVersion Include="Microsoft.Spatial" Version="8.2.0" />
25+
<PackageVersion Include="NSubstitute" Version="5.3.0" />
26+
<PackageVersion Include="NSwag.AspNetCore" Version="14.1.0" />
27+
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
28+
<PackageVersion Include="Swashbuckle.AspNetCore" Version="7.0.0" />
29+
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
3030
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
31+
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
32+
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
3133
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
32-
<PackageVersion Include="xunit" Version="2.7.0" />
33-
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" />
34+
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="8.0.1" />
35+
<PackageVersion Include="xunit" Version="2.9.2" />
36+
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
3437
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
3538
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
3639
<PackageVersion Include="Ulid" Version="1.3.4" />

src/CommunityToolkit.Datasync.Client/CommunityToolkit.Datasync.Client.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<Description>The client capabilities for developing applications using the Datasync Toolkit.</Description>
44
</PropertyGroup>
@@ -12,7 +12,7 @@
1212
<PackageReference Include="Microsoft.EntityFrameworkCore" />
1313
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
1414
<PackageReference Include="Microsoft.Extensions.Http" />
15-
<PackageReference Include="Microsoft.Azure.Core.Spatial" />
1615
<PackageReference Include="System.Threading.Tasks.Dataflow" />
16+
<PackageReference Include="Microsoft.Spatial" />
1717
</ItemGroup>
1818
</Project>

src/CommunityToolkit.Datasync.Client/Paging/ConcurrentObservableCollection.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace CommunityToolkit.Datasync.Client;
1616
/// <typeparam name="T"></typeparam>
1717
public class ConcurrentObservableCollection<T> : ObservableCollection<T>
1818
{
19-
private readonly SynchronizationContext context = SynchronizationContext.Current!;
19+
private readonly SynchronizationContext? currentContext = SynchronizationContext.Current;
2020
private bool suppressNotification = false;
2121

2222
/// <summary>
@@ -151,31 +151,30 @@ public bool ReplaceIf(Func<T, bool> match, T replacement)
151151
/// </summary>
152152
/// <param name="e">The event arguments</param>
153153
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
154-
=> DispatchCallback(new SynchronizationContextAdapter(this.context), RaiseCollectionChanged, e);
154+
{
155+
if (this.currentContext is null || SynchronizationContext.Current == this.currentContext)
156+
{
157+
RaiseCollectionChanged(e);
158+
}
159+
else
160+
{
161+
this.currentContext.Send(RaiseCollectionChanged, e);
162+
}
163+
}
155164

156165
/// <summary>
157166
/// Event trigger to indicate that a property has changed in a thread-safe way.
158167
/// </summary>
159168
/// <param name="e">The event arguments</param>
160169
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
161-
=> DispatchCallback(new SynchronizationContextAdapter(this.context), RaisePropertyChanged, e);
162-
163-
/// <summary>
164-
/// Dispatches the callback to the synchronization context. If the synchronization context is
165-
/// the current one, we can avoid a dispatch and just call the callback directly.
166-
/// </summary>
167-
/// <param name="context">The context to send the request to.</param>
168-
/// <param name="callback">The callback method.</param>
169-
/// <param name="param">The parameter for the callback method.</param>
170-
internal static void DispatchCallback(ISynchronizationContext context, SendOrPostCallback callback, object? param)
171170
{
172-
if (context.IsCurrentContext())
171+
if (this.currentContext is null || SynchronizationContext.Current == this.currentContext)
173172
{
174-
callback(param);
173+
RaisePropertyChanged(e);
175174
}
176175
else
177176
{
178-
context.Send(callback, param);
177+
this.currentContext.Send(RaisePropertyChanged, e);
179178
}
180179
}
181180

src/CommunityToolkit.Datasync.Client/Paging/SynchronizationContextAdapter.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/CommunityToolkit.Datasync.Client/Serialization/DatasyncSerializer.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using Azure.Core.Serialization;
65
using System.Text.Json;
76
using System.Text.Json.Serialization;
87

@@ -58,7 +57,7 @@ public static string Serialize(object obj, Type objType)
5857
new DateTimeOffsetConverter(),
5958
new DateTimeConverter(),
6059
new TimeOnlyConverter(),
61-
new MicrosoftSpatialGeoJsonConverter()
60+
new SpatialGeoJsonConverter()
6261
},
6362
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
6463
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Text.Json;
6+
7+
namespace CommunityToolkit.Datasync.Client.Serialization;
8+
9+
/// <summary>
10+
/// Extension methods for System.Text.Json.
11+
/// </summary>
12+
internal static class JsonExtensions
13+
{
14+
/// <summary>
15+
/// Asserts that the current token of the <see cref="Utf8JsonReader"/> matches the <paramref name="expectedTokenType"/>.
16+
/// </summary>
17+
/// <param name="reader">The <see cref="Utf8JsonReader"/> to assert.</param>
18+
/// <param name="expectedTokenType">The expected <see cref="JsonTokenType"/> of the current token.</param>
19+
/// <exception cref="JsonException">The current token did not match the <paramref name="expectedTokenType"/>.</exception>
20+
public static void Expect(in this Utf8JsonReader reader, JsonTokenType expectedTokenType)
21+
{
22+
if (reader.TokenType != expectedTokenType)
23+
{
24+
throw new JsonException($"Deserialization failed. Expected token: '{expectedTokenType}'.");
25+
}
26+
}
27+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.Spatial;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
9+
namespace CommunityToolkit.Datasync.Client.Serialization;
10+
11+
/// <summary>
12+
/// Converters between Microsoft.Spatial types and GeoJSON
13+
/// </summary>
14+
/// <remarks>
15+
/// Only handles GeographyPoint at this time.
16+
/// </remarks>
17+
/// <see href="https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.Spatial_1.1.0/sdk/core/Microsoft.Azure.Core.Spatial/src/Serialization" />
18+
public class SpatialGeoJsonConverter : JsonConverter<object>
19+
{
20+
private const string CoordinatesPropertyName = "coordinates";
21+
private const string PointTypeName = "Point";
22+
private const string TypePropertyName = "type";
23+
24+
private static readonly JsonEncodedText s_CoordinatesPropertyNameBytes = JsonEncodedText.Encode(CoordinatesPropertyName);
25+
private static readonly JsonEncodedText s_TypePropertyNameBytes = JsonEncodedText.Encode(TypePropertyName);
26+
27+
/// <inheritdoc/>
28+
public override bool CanConvert(Type typeToConvert) =>
29+
typeof(GeographyPoint).IsAssignableFrom(typeToConvert);
30+
31+
/// <inheritdoc/>
32+
public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
33+
{
34+
if (reader.TokenType == JsonTokenType.Null)
35+
{
36+
return null;
37+
}
38+
39+
string? type = default;
40+
double? longitude = default;
41+
double? latitude = default;
42+
43+
reader.Expect(JsonTokenType.StartObject);
44+
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
45+
{
46+
reader.Expect(JsonTokenType.PropertyName);
47+
string? propertyName = reader.GetString();
48+
49+
_ = reader.Read();
50+
if (string.Equals(TypePropertyName, propertyName, StringComparison.Ordinal))
51+
{
52+
reader.Expect(JsonTokenType.String);
53+
type = reader.GetString();
54+
}
55+
else if (string.Equals(CoordinatesPropertyName, propertyName, StringComparison.Ordinal))
56+
{
57+
reader.Expect(JsonTokenType.StartArray);
58+
59+
// Longitude
60+
_ = reader.Read();
61+
reader.Expect(JsonTokenType.Number);
62+
longitude = reader.GetDouble();
63+
64+
// Latitude
65+
_ = reader.Read();
66+
reader.Expect(JsonTokenType.Number);
67+
latitude = reader.GetDouble();
68+
69+
// Skip the rest.
70+
do
71+
{
72+
_ = reader.Read();
73+
} while (reader.TokenType != JsonTokenType.EndArray);
74+
}
75+
else
76+
{
77+
reader.Skip();
78+
}
79+
}
80+
81+
if (!string.Equals(PointTypeName, type, StringComparison.Ordinal))
82+
{
83+
throw new JsonException($"Deserialization of {nameof(GeographyPoint)} failed. Expected geographic type: '{PointTypeName}'.");
84+
}
85+
86+
if (!longitude.HasValue || !latitude.HasValue)
87+
{
88+
throw new JsonException($"Deserialization of {nameof(GeographyPoint)} failed. Expected both longitude and latitude.");
89+
}
90+
91+
return GeographyPoint.Create(latitude.Value, longitude.Value);
92+
}
93+
94+
/// <inheritdoc/>
95+
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
96+
{
97+
if (value is GeographyPoint point)
98+
{
99+
writer.WriteStartObject();
100+
writer.WriteString(s_TypePropertyNameBytes, PointTypeName);
101+
writer.WriteStartArray(s_CoordinatesPropertyNameBytes);
102+
writer.WriteNumberValue(point.Longitude);
103+
writer.WriteNumberValue(point.Latitude);
104+
writer.WriteEndArray();
105+
writer.WriteEndObject();
106+
}
107+
}
108+
}

src/CommunityToolkit.Datasync.Server.Abstractions/CommunityToolkit.Datasync.Server.Abstractions.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<PropertyGroup>
33
<Description>Abstractions for developing server-side applications using the Datasync Toolkit.</Description>
44
</PropertyGroup>
5-
65
<ItemGroup>
7-
<PackageReference Include="Microsoft.Azure.Core.Spatial" />
6+
<PackageReference Include="Microsoft.Spatial" />
87
</ItemGroup>
98
</Project>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Text.Json;
6+
7+
namespace CommunityToolkit.Datasync.Server.Abstractions.Json;
8+
9+
/// <summary>
10+
/// Extension methods for System.Text.Json.
11+
/// </summary>
12+
internal static class JsonExtensions
13+
{
14+
/// <summary>
15+
/// Asserts that the current token of the <see cref="Utf8JsonReader"/> matches the <paramref name="expectedTokenType"/>.
16+
/// </summary>
17+
/// <param name="reader">The <see cref="Utf8JsonReader"/> to assert.</param>
18+
/// <param name="expectedTokenType">The expected <see cref="JsonTokenType"/> of the current token.</param>
19+
/// <exception cref="JsonException">The current token did not match the <paramref name="expectedTokenType"/>.</exception>
20+
public static void Expect(in this Utf8JsonReader reader, JsonTokenType expectedTokenType)
21+
{
22+
if (reader.TokenType != expectedTokenType)
23+
{
24+
throw new JsonException($"Deserialization failed. Expected token: '{expectedTokenType}'.");
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)