9cff87fe85
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.
62 lines
2.6 KiB
C#
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;
|
|
}
|
|
}
|