Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.CentralUI/Services/SchemaLibraryQueryService.cs
T
Joseph Doherty 9cff87fe85 docs(comments): strip internal task/milestone/bundle bookkeeping from code comments
Remove project bookkeeping citations from shipped code comments across the
solution: hyphenated task IDs (WP-14, StoreAndForward-025), milestone/task/
issue refs (M3, Task 4, Audit Log #23, #21), Bundle X task-bundle labels,
and C/D/K/S/T phase labels.

Comment text only — no code logic, string/log literals, or XML-doc structure
changed. Genuine descriptions are preserved (only the citation is stripped),
and technical lookalikes are retained (UTF-8, SHA-256, T00:00:00, M365,
UTC-5, pre-C4/pre-C5 schema versions). Flagged by the new CommentChecker
TaskReferenceInComment / TrackingReferenceInComment checks plus targeted
grep passes; full solution builds clean, append-only guard tests pass.
2026-07-07 11:03:26 -04:00

62 lines
2.6 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
/// <summary>
/// Default <see cref="ISchemaLibraryQueryService"/> implementation. Reads the
/// named JSON-Schema library directly from <see cref="ISharedSchemaRepository"/> over a
/// fresh DI scope per query — mirroring <c>AuditLogQueryService</c> /
/// <c>KpiHistoryQueryService</c> so a value form's auto-load never races other reads on
/// the shared circuit-scoped DbContext. Read-only; no mutation goes through here.
/// </summary>
public sealed class SchemaLibraryQueryService : ISchemaLibraryQueryService
{
private readonly IServiceScopeFactory _scopeFactory;
/// <summary>
/// Initializes a new instance of the <see cref="SchemaLibraryQueryService"/>.
/// </summary>
/// <param name="scopeFactory">Factory used to open a fresh DI scope (and DbContext) per query.</param>
public SchemaLibraryQueryService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
}
/// <inheritdoc/>
public async Task<IReadOnlyDictionary<string, string>> GetSchemaMapAsync(
CancellationToken cancellationToken = default)
{
await using var scope = _scopeFactory.CreateAsyncScope();
var repo = scope.ServiceProvider.GetRequiredService<ISharedSchemaRepository>();
var all = await repo.ListAsync(cancellationToken);
// Ordinal-keyed to match the lib:Name resolver's exact-name lookup. Name is
// DB-unique, so a list yields at most one row per name and no real collision
// occurs; the indexer assignment is defensive only — should two rows ever share
// a name (e.g. a mid-write transient read), the later one in enumeration order
// overwrites the earlier rather than throwing.
var map = new Dictionary<string, string>(StringComparer.Ordinal);
foreach (var schema in all)
{
map[schema.Name] = schema.SchemaJson;
}
return map;
}
/// <inheritdoc/>
public async Task<string?> ResolveAsync(string name, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(name))
{
return null;
}
await using var scope = _scopeFactory.CreateAsyncScope();
var repo = scope.ServiceProvider.GetRequiredService<ISharedSchemaRepository>();
var schema = await repo.GetByNameAsync(name, cancellationToken);
return schema?.SchemaJson;
}
}