Files
git.stella-ops.org/src/AdvisoryAI/StellaOps.AdvisoryAI.Scm.Plugin.Unified/ScmPluginAdapterFactory.cs
2026-02-01 21:37:40 +02:00

136 lines
4.3 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using StellaOps.AdvisoryAI.Remediation.ScmConnector;
using StellaOps.Plugin.Abstractions;
using StellaOps.Plugin.Abstractions.Capabilities;
namespace StellaOps.AdvisoryAI.Scm.Plugin.Unified;
/// <summary>
/// Factory for creating unified SCM plugin adapters from existing connectors.
/// </summary>
public sealed class ScmPluginAdapterFactory
{
private readonly ScmConnectorCatalog _catalog;
private readonly Dictionary<string, ScmPluginAdapter> _adapters = new(StringComparer.OrdinalIgnoreCase);
private readonly object _lock = new();
/// <summary>
/// Creates a new factory instance.
/// </summary>
/// <param name="catalog">The SCM connector catalog.</param>
public ScmPluginAdapterFactory(ScmConnectorCatalog catalog)
{
_catalog = catalog ?? throw new ArgumentNullException(nameof(catalog));
}
/// <summary>
/// Gets all available unified SCM plugins.
/// </summary>
/// <param name="options">Connector options.</param>
/// <returns>List of unified SCM plugins.</returns>
public IReadOnlyList<IPlugin> GetAllPlugins(ScmConnectorOptions options)
{
var result = new List<IPlugin>();
foreach (var plugin in _catalog.Plugins)
{
if (plugin.IsAvailable(options))
{
var adapter = GetOrCreateAdapter(plugin.ScmType, options);
if (adapter != null)
{
result.Add(adapter);
}
}
}
return result;
}
/// <summary>
/// Gets a unified SCM plugin by SCM type.
/// </summary>
/// <param name="scmType">SCM type identifier.</param>
/// <param name="options">Connector options.</param>
/// <returns>Unified SCM plugin, or null if not found.</returns>
public IPlugin? GetPlugin(string scmType, ScmConnectorOptions options)
{
return GetOrCreateAdapter(scmType, options);
}
/// <summary>
/// Gets a unified SCM plugin that can handle the given repository URL.
/// </summary>
/// <param name="repositoryUrl">Repository URL to handle.</param>
/// <param name="options">Connector options.</param>
/// <returns>Unified SCM plugin, or null if not found.</returns>
public IPlugin? GetPluginForRepository(string repositoryUrl, ScmConnectorOptions options)
{
var plugin = _catalog.Plugins.FirstOrDefault(p => p.CanHandle(repositoryUrl));
if (plugin == null)
return null;
return GetOrCreateAdapter(plugin.ScmType, options);
}
/// <summary>
/// Gets the SCM capability for a connector.
/// </summary>
/// <param name="scmType">SCM type identifier.</param>
/// <param name="options">Connector options.</param>
/// <returns>SCM capability, or null if not found.</returns>
public IScmCapability? GetCapability(string scmType, ScmConnectorOptions options)
{
return GetOrCreateAdapter(scmType, options);
}
private ScmPluginAdapter? GetOrCreateAdapter(string scmType, ScmConnectorOptions options)
{
lock (_lock)
{
if (_adapters.TryGetValue(scmType, out var existing))
{
return existing;
}
var plugin = _catalog.Plugins.FirstOrDefault(
p => p.ScmType.Equals(scmType, StringComparison.OrdinalIgnoreCase));
if (plugin == null || !plugin.IsAvailable(options))
{
return null;
}
var connector = _catalog.GetConnector(scmType, options);
if (connector == null)
{
return null;
}
var adapter = new ScmPluginAdapter(connector, plugin, options);
_adapters[scmType] = adapter;
return adapter;
}
}
}
/// <summary>
/// Extension methods for registering unified SCM plugin services.
/// </summary>
public static class ScmPluginAdapterExtensions
{
/// <summary>
/// Adds unified SCM plugin adapter services to the service collection.
/// </summary>
/// <param name="services">Service collection.</param>
/// <returns>Service collection for chaining.</returns>
public static IServiceCollection AddUnifiedScmPlugins(this IServiceCollection services)
{
services.AddSingleton<ScmPluginAdapterFactory>();
return services;
}
}