File: AtsContextFactory.cs
Web Access
Project: src\src\Aspire.Hosting.RemoteHost\Aspire.Hosting.RemoteHost.csproj (Aspire.Hosting.RemoteHost)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Reflection;
using Aspire.Hosting.Ats;
using Microsoft.Extensions.Logging;
 
namespace Aspire.Hosting.RemoteHost;
 
/// <summary>
/// Factory for creating a shared <see cref="AtsContext"/> from loaded assemblies.
/// </summary>
internal sealed class AtsContextFactory
{
    private readonly Lazy<AtsContext> _context;
 
    public AtsContextFactory(AssemblyLoader assemblyLoader, ILogger<AtsContextFactory> logger)
    {
        _context = new Lazy<AtsContext>(() => Create(assemblyLoader.GetAssemblies(), logger));
    }
 
    /// <summary>
    /// Gets or creates the <see cref="AtsContext"/> by scanning the loaded assemblies.
    /// </summary>
    /// <returns>The scanned ATS context.</returns>
    public AtsContext GetContext() => _context.Value;
 
    private static AtsContext Create(IReadOnlyList<Assembly> assemblies, ILogger logger)
    {
        logger.LogDebug("Creating AtsContext from {AssemblyCount} assemblies...", assemblies.Count);
 
        // Scan all assemblies using multi-pass scanning
        var result = AtsCapabilityScanner.ScanAssemblies(assemblies);
 
        // Log diagnostics
        foreach (var diagnostic in result.Diagnostics)
        {
            if (diagnostic.Severity == AtsDiagnosticSeverity.Error)
            {
                logger.LogError("[ATS] {Message} at {Location}", diagnostic.Message, diagnostic.Location);
            }
            else
            {
                logger.LogWarning("[ATS] {Message} at {Location}", diagnostic.Message, diagnostic.Location);
            }
        }
 
        logger.LogDebug("Scanned {CapabilityCount} capabilities, {HandleTypeCount} handle types, {DtoCount} DTOs, {EnumCount} enums",
            result.Capabilities.Count, result.HandleTypes.Count, result.DtoTypes.Count, result.EnumTypes.Count);
 
        return result.ToAtsContext();
    }
}