Skip to content

Commit ad7c470

Browse files
committed
Add XML documentation to public API and enable doc generation for NuGet packages
Add comprehensive XML doc comments (summary, param, returns, exception tags) to all public types across the library: configuration builders, core interfaces, sync agent, model classes, enums, extension methods, and HTTP client/server API. Configure all library .csproj files to generate XML documentation files in Release mode so they are automatically included in NuGet packages. Fix broken cref references in InvalidSyncOperationException.
1 parent 6c2daf9 commit ad7c470

40 files changed

Lines changed: 1186 additions & 134 deletions

‎.gitignore‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,5 +326,8 @@ ASALocalRun/
326326
# NVidia Nsight GPU debugger configuration file
327327
*.nvuser
328328

329-
# MFractors (Xamarin productivity tool) working folder
329+
# MFractors (Xamarin productivity tool) working folder
330330
.mfractor/
331+
332+
# Claude Code
333+
.claude/

‎src/CoreSync.Http.Client/CoreSync.Http.Client.csproj‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
<NoWarn>RS1036,NU1903,NU1902,NU1901,NU1904</NoWarn>
2020
</PropertyGroup>
2121

22+
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
23+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
24+
<NoWarn>$(NoWarn);CS1591</NoWarn>
25+
</PropertyGroup>
26+
2227
<ItemGroup>
2328
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.0" />
2429
<PackageReference Include="MessagePack" Version="2.5.187" />

‎src/CoreSync.Http.Client/ISyncProviderHttpClient.cs‎

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,81 @@
1-
using System;
1+
using System;
22

33
namespace CoreSync.Http.Client;
44

5+
/// <summary>
6+
/// A sync provider that communicates with a remote CoreSync server over HTTP.
7+
/// Extends <see cref="ISyncProviderBase"/> with progress reporting.
8+
/// </summary>
59
public interface ISyncProviderHttpClient : ISyncProviderBase
610
{
11+
/// <summary>
12+
/// Occurs when the synchronization progresses through different stages, allowing UI updates
13+
/// or progress reporting.
14+
/// </summary>
715
event EventHandler<SyncProgressEventArgs> SyncProgress;
816
}
917

18+
/// <summary>
19+
/// Provides data for the <see cref="ISyncProviderHttpClient.SyncProgress"/> event.
20+
/// </summary>
1021
public class SyncProgressEventArgs : EventArgs
1122
{
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="SyncProgressEventArgs"/> class.
25+
/// </summary>
26+
/// <param name="stage">The current synchronization stage.</param>
27+
/// <param name="progress">
28+
/// An optional progress value between 0.0 and 1.0, or <c>null</c> if progress is indeterminate.
29+
/// </param>
1230
public SyncProgressEventArgs(SyncStage stage, double? progress = null)
1331
{
1432
Stage = stage;
1533
Progress = progress;
1634
}
1735

36+
/// <summary>
37+
/// Gets the current synchronization stage.
38+
/// </summary>
1839
public SyncStage Stage { get; }
40+
41+
/// <summary>
42+
/// Gets the progress value (0.0 to 1.0), or <c>null</c> if progress is indeterminate.
43+
/// </summary>
1944
public double? Progress { get; }
2045
}
2146

47+
/// <summary>
48+
/// Identifies the current stage of an HTTP-based synchronization operation.
49+
/// </summary>
2250
public enum SyncStage
2351
{
52+
/// <summary>
53+
/// Performing the initial snapshot transfer for a first-time sync.
54+
/// </summary>
2455
InitialSnapshot,
2556

57+
/// <summary>
58+
/// Computing local changes to upload to the server.
59+
/// </summary>
2660
ComputingLocalChanges,
2761

62+
/// <summary>
63+
/// Applying local changes to the remote server.
64+
/// </summary>
2865
ApplyChanges,
2966

67+
/// <summary>
68+
/// Computing remote changes to download from the server.
69+
/// </summary>
3070
ComputingRemotingChanges,
3171

72+
/// <summary>
73+
/// Downloading remote changes from the server.
74+
/// </summary>
3275
GetChanges,
3376

77+
/// <summary>
78+
/// Applying downloaded remote changes to the local store.
79+
/// </summary>
3480
ApplyChangesLocally
3581
}
36-

‎src/CoreSync.Http.Client/ServiceCollectionExtensions.cs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.DependencyInjection;
22
using System;
33
using System.Collections.Generic;
44
using System.Text;
55

66
namespace CoreSync.Http.Client;
77

8+
/// <summary>
9+
/// Extension methods for registering CoreSync HTTP client services in the dependency injection container.
10+
/// </summary>
811
public static class ServiceCollectionExtensions
912
{
13+
/// <summary>
14+
/// Registers the <see cref="ISyncProviderHttpClient"/> and its dependencies in the service collection.
15+
/// </summary>
16+
/// <param name="services">The service collection to add services to.</param>
17+
/// <param name="optionsConfigure">
18+
/// An optional action to configure <see cref="SyncProviderHttpClientOptions"/>.
19+
/// </param>
1020
public static void AddCoreSyncHttpClient(this IServiceCollection services, Action<SyncProviderHttpClientOptions>? optionsConfigure = null)
1121
{
1222
var options = new SyncProviderHttpClientOptions();
Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Text;
44

55
namespace CoreSync.Http.Client;
66

7+
/// <summary>
8+
/// Configuration options for <see cref="ISyncProviderHttpClient"/>.
9+
/// </summary>
710
public class SyncProviderHttpClientOptions
811
{
12+
/// <summary>
13+
/// Gets or sets the route prefix for the sync controller endpoints on the server.
14+
/// Defaults to <c>"api/sync-agent"</c>.
15+
/// </summary>
916
public string SyncControllerRoute { get; set; } = "api/sync-agent";
1017

18+
/// <summary>
19+
/// Gets or sets the named <see cref="System.Net.Http.HttpClient"/> to resolve from
20+
/// <see cref="System.Net.Http.IHttpClientFactory"/>. When <c>null</c>, the default client is used.
21+
/// </summary>
1122
public string? HttpClientName { get; set; }
1223

24+
/// <summary>
25+
/// Gets or sets the number of sync items sent or received per bulk request.
26+
/// Defaults to 50.
27+
/// </summary>
1328
public int BulkItemSize { get; set; } = 50;
1429

30+
/// <summary>
31+
/// Gets or sets the maximum number of retry attempts for transient HTTP failures (using Polly).
32+
/// Defaults to 3.
33+
/// </summary>
1534
public int MaxRetryAttempts { get; set; } = 3;
1635

36+
/// <summary>
37+
/// Gets or sets a value indicating whether to use MessagePack binary format for HTTP payloads.
38+
/// When <c>false</c>, JSON is used. Defaults to <c>false</c>.
39+
/// </summary>
1740
public bool UseBinaryFormat { get; set; }
1841
}

‎src/CoreSync.Http.Server/CoreSync.Http.Server.csproj‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@
1818
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
1919
<NoWarn>RS1036,NU1903,NU1902,NU1901,NU1904</NoWarn>
2020
</PropertyGroup>
21-
21+
22+
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
23+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
24+
<NoWarn>$(NoWarn);CS1591</NoWarn>
25+
</PropertyGroup>
26+
2227
<ItemGroup>
2328
<FrameworkReference Include="Microsoft.AspNetCore.App" />
2429
<PackageReference Include="MessagePack.AspNetCoreMvcFormatter" Version="2.5.187" />

‎src/CoreSync.Http.Server/ServiceCollectionExtensions.cs‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.DependencyInjection;
22

33
namespace CoreSync.Http.Server;
44

5+
/// <summary>
6+
/// Extension methods for registering CoreSync HTTP server services in the dependency injection container.
7+
/// </summary>
58
public static class ServiceCollectionExtensions
69
{
10+
/// <summary>
11+
/// Registers the CoreSync HTTP server controller and its dependencies (memory cache) in the service collection.
12+
/// </summary>
13+
/// <param name="services">The service collection to add services to.</param>
714
public static void AddCoreSyncHttpServer(this IServiceCollection services)
815
{
916
services.AddMemoryCache();
Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,68 @@
1-
using Microsoft.AspNetCore.Builder;
1+
using Microsoft.AspNetCore.Builder;
22
using System;
33

44
namespace CoreSync.Http.Server;
55

6+
/// <summary>
7+
/// Provides per-endpoint customization hooks for the CoreSync HTTP server endpoints.
8+
/// Each property allows configuring the corresponding endpoint (e.g., adding authorization, rate limiting, or CORS).
9+
/// </summary>
610
public class SyncControllerOptions
711
{
12+
/// <summary>
13+
/// Gets or sets an action applied to all sync endpoints. Use this to add shared middleware
14+
/// such as authorization or CORS policies.
15+
/// </summary>
816
public Action<IEndpointConventionBuilder>? AllEndpoints { get; set; }
917

18+
/// <summary>
19+
/// Gets or sets an action to configure the GET store-id endpoint.
20+
/// </summary>
1021
public Action<IEndpointConventionBuilder>? GetStoreIdEndpoint { get; set; }
1122

23+
/// <summary>
24+
/// Gets or sets an action to configure the GET bulk change set endpoint.
25+
/// </summary>
1226
public Action<IEndpointConventionBuilder>? GetBulkChangeSetAsyncEndPoint { get; set; }
1327

28+
/// <summary>
29+
/// Gets or sets an action to configure the GET bulk change set item (JSON) endpoint.
30+
/// </summary>
1431
public Action<IEndpointConventionBuilder>? GetBulkChangeSetItemEndPoint { get; set; }
1532

33+
/// <summary>
34+
/// Gets or sets an action to configure the GET bulk change set item (binary/MessagePack) endpoint.
35+
/// </summary>
1636
public Action<IEndpointConventionBuilder>? GetBulkChangeSetItemBinaryEndPoint { get; set; }
1737

38+
/// <summary>
39+
/// Gets or sets an action to configure the POST begin-apply-bulk-changes endpoint.
40+
/// </summary>
1841
public Action<IEndpointConventionBuilder>? PostBeginApplyBulkChangesEndPoint { get; set; }
1942

43+
/// <summary>
44+
/// Gets or sets an action to configure the POST apply-bulk-changes-item (JSON) endpoint.
45+
/// </summary>
2046
public Action<IEndpointConventionBuilder>? PostApplyBulkChangesItemEndPoint { get; set; }
2147

22-
public Action<IEndpointConventionBuilder>? PostApplyBulkChangesItemBinaryEndPoint { get; set; }
48+
/// <summary>
49+
/// Gets or sets an action to configure the POST apply-bulk-changes-item (binary/MessagePack) endpoint.
50+
/// </summary>
51+
public Action<IEndpointConventionBuilder>? PostApplyBulkChangesItemBinaryEndPoint { get; set; }
2352

53+
/// <summary>
54+
/// Gets or sets an action to configure the POST complete-apply-bulk-changes (JSON) endpoint.
55+
/// </summary>
2456
public Action<IEndpointConventionBuilder>? PostCompleteApplyBulkChangesAsyncEndPoint { get; set; }
2557

58+
/// <summary>
59+
/// Gets or sets an action to configure the POST complete-apply-bulk-changes (binary/MessagePack) endpoint.
60+
/// </summary>
2661
public Action<IEndpointConventionBuilder>? PostCompleteApplyBulkChangesBinaryAsyncEndPoint { get; set; }
2762

63+
/// <summary>
64+
/// Gets or sets an action to configure the POST save-version-for-store endpoint.
65+
/// </summary>
2866
public Action<IEndpointConventionBuilder>? PostSaveVersionForStoreAsyncEndPoint { get; set; }
2967

3068
}

‎src/CoreSync.Http.Server/WebApplicationExtensions.cs‎

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using MessagePack.AspNetCoreMvcFormatter;
1+
using MessagePack.AspNetCoreMvcFormatter;
22
using Microsoft.AspNetCore.Builder;
33
using Microsoft.AspNetCore.Http;
44
using Microsoft.AspNetCore.Mvc;
@@ -13,13 +13,31 @@
1313

1414
namespace CoreSync.Http.Server;
1515

16+
/// <summary>
17+
/// Extension methods for mapping CoreSync HTTP server endpoints in an ASP.NET Core application.
18+
/// </summary>
1619
public static class WebApplicationExtensions
1720
{
21+
/// <summary>
22+
/// Maps all CoreSync synchronization endpoints on the specified <see cref="WebApplication"/>.
23+
/// </summary>
24+
/// <param name="webApplication">The web application to add endpoints to.</param>
25+
/// <param name="route">The route prefix for all sync endpoints. Defaults to <c>"api/sync-agent"</c>.</param>
26+
/// <param name="optionsConfigure">An optional action to configure per-endpoint options via <see cref="SyncControllerOptions"/>.</param>
27+
/// <exception cref="ArgumentException"><paramref name="route"/> is <c>null</c>, empty, or whitespace.</exception>
1828
public static void UseCoreSyncHttpServer(this WebApplication webApplication, string route = "api/sync-agent", Action<SyncControllerOptions>? optionsConfigure = null)
1929
{
2030
webApplication.MapCoreSyncHttpServerEndpoints(route, optionsConfigure);
2131
}
2232

33+
/// <summary>
34+
/// Maps all CoreSync synchronization endpoints on the specified <see cref="IEndpointRouteBuilder"/>.
35+
/// Use this overload when configuring endpoints outside of <see cref="WebApplication"/> (e.g., inside route groups).
36+
/// </summary>
37+
/// <param name="webApplication">The endpoint route builder to add endpoints to.</param>
38+
/// <param name="route">The route prefix for all sync endpoints. Defaults to <c>"api/sync-agent"</c>.</param>
39+
/// <param name="optionsConfigure">An optional action to configure per-endpoint options via <see cref="SyncControllerOptions"/>.</param>
40+
/// <exception cref="ArgumentException"><paramref name="route"/> is <c>null</c>, empty, or whitespace.</exception>
2341
public static void MapCoreSyncHttpServerEndpoints(this IEndpointRouteBuilder webApplication, string route = "api/sync-agent", Action<SyncControllerOptions>? optionsConfigure = null)
2442
{
2543
if (string.IsNullOrWhiteSpace(route))
@@ -36,18 +54,18 @@ void ConfigureEndpoint<T>(T endpoint, Action<T>? specificAction = null) where T
3654
specificAction?.Invoke(endpoint);
3755
}
3856

39-
var getStoreEndPoint = webApplication.MapGet($"/{route}/store-id",
40-
([FromServices] SyncAgentController controller)
57+
var getStoreEndPoint = webApplication.MapGet($"/{route}/store-id",
58+
([FromServices] SyncAgentController controller)
4159
=> controller.GetStoreIdAsync());
4260
ConfigureEndpoint(getStoreEndPoint, options.GetStoreIdEndpoint);
4361

44-
var getBulkChangeSetAsyncEndPoint = webApplication.MapGet($"/{route}/changes-bulk/{{storeId}}",
62+
var getBulkChangeSetAsyncEndPoint = webApplication.MapGet($"/{route}/changes-bulk/{{storeId}}",
4563
(string storeId, [FromServices] SyncAgentController controller)
4664
=> controller.GetBulkChangeSetAsync(Guid.Parse(storeId)));
4765
ConfigureEndpoint(getBulkChangeSetAsyncEndPoint, options.GetBulkChangeSetAsyncEndPoint);
4866

4967
var getBulkChangeSetItemEndPoint = webApplication.MapGet(
50-
$"/{route}/changes-bulk-item/{{sessionId}}/{{skip}}/{{take}}",
68+
$"/{route}/changes-bulk-item/{{sessionId}}/{{skip}}/{{take}}",
5169
(string sessionId, int skip, int take, [FromServices] SyncAgentController controller)
5270
=> controller.GetBulkChangeSetItem(new BulkChangeSetDownloadItem
5371
{
@@ -72,14 +90,14 @@ void ConfigureEndpoint<T>(T endpoint, Action<T>? specificAction = null) where T
7290
ConfigureEndpoint(getBulkChangeSetItemBinaryEndPoint, options.GetBulkChangeSetItemBinaryEndPoint);
7391

7492
var postBeginApplyBulkChangesEndPoint = webApplication.MapPost(
75-
$"/{route}/changes-bulk-begin",
76-
([FromBody] BulkSyncChangeSet bulkChangeSet, [FromServices] SyncAgentController controller)
93+
$"/{route}/changes-bulk-begin",
94+
([FromBody] BulkSyncChangeSet bulkChangeSet, [FromServices] SyncAgentController controller)
7795
=> controller.BeginApplyBulkChanges(bulkChangeSet));
7896

7997
ConfigureEndpoint(postBeginApplyBulkChangesEndPoint, options.PostBeginApplyBulkChangesEndPoint);
8098

8199
var postApplyBulkChangesItemEndPoint = webApplication.MapPost(
82-
$"/{route}/changes-bulk-item",
100+
$"/{route}/changes-bulk-item",
83101
([FromBody] BulkChangeSetUploadItem bulkUploadItem, [FromServices] SyncAgentController controller)
84102
=> controller.ApplyBulkChangesItem(bulkUploadItem));
85103
ConfigureEndpoint(postApplyBulkChangesItemEndPoint, options.PostApplyBulkChangesItemEndPoint);
@@ -92,8 +110,8 @@ void ConfigureEndpoint<T>(T endpoint, Action<T>? specificAction = null) where T
92110
ConfigureEndpoint(postApplyBulkChangesItemBinaryEndPoint, options.PostApplyBulkChangesItemBinaryEndPoint);
93111

94112
var postCompleteApplyBulkChangesAsyncEndPoint = webApplication.MapPost(
95-
$"/{route}/changes-bulk-complete/{{sessionId}}",
96-
(string sessionId, [FromServices] SyncAgentController controller)
113+
$"/{route}/changes-bulk-complete/{{sessionId}}",
114+
(string sessionId, [FromServices] SyncAgentController controller)
97115
=> controller.CompleteApplyBulkChangesAsync(Guid.Parse(sessionId)));
98116
ConfigureEndpoint(postCompleteApplyBulkChangesAsyncEndPoint, options.PostCompleteApplyBulkChangesAsyncEndPoint);
99117

@@ -104,8 +122,8 @@ void ConfigureEndpoint<T>(T endpoint, Action<T>? specificAction = null) where T
104122
ConfigureEndpoint(postCompleteApplyBulkChangesBinaryAsyncEndPoint, options.PostCompleteApplyBulkChangesBinaryAsyncEndPoint);
105123

106124
var postSaveVersionForStoreAsyncEndPoint = webApplication.MapPost(
107-
$"/{route}/save-version/{{storeId}}/{{version}}",
108-
(string storeId, long version, [FromServices] SyncAgentController controller)
125+
$"/{route}/save-version/{{storeId}}/{{version}}",
126+
(string storeId, long version, [FromServices] SyncAgentController controller)
109127
=> controller.SaveVersionForStoreAsync(Guid.Parse(storeId), version));
110128
ConfigureEndpoint(postSaveVersionForStoreAsyncEndPoint, options.PostSaveVersionForStoreAsyncEndPoint);
111129
}
@@ -154,4 +172,4 @@ await messagePackFormatter.WriteAsync(new OutputFormatterWriteContext(
154172
return builder;
155173
}
156174

157-
}
175+
}

0 commit comments

Comments
 (0)