Repository: dotnet/roslyn
File: src/VisualStudio/Core/Def/ProjectSystem/SdkAnalyzerAssemblyRedirector.cs (C#)

Code before:
/// </summary>
[Export(typeof(IAnalyzerAssemblyRedirector))]
internal sealed class SdkAnalyzerAssemblyRedirector : IAnalyzerAssemblyRedirector
{
    private readonly IVsActivityLog? _log;

    private readonly bool _enabled;

    private readonly string? _insertedAnalyzersDirectory;

    /// <summary>
    /// Map from analyzer assembly name (file name without extension) to a list of matching analyzers.
    /// </summary>
    private readonly ImmutableDictionary<string, List<AnalyzerInfo>> _analyzerMap;

    [ImportingConstructor]
    [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
    public SdkAnalyzerAssemblyRedirector(SVsServiceProvider serviceProvider) : this(
        Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"CommonExtensions\Microsoft\DotNet")),
        serviceProvider.GetServiceOnMainThread<SVsActivityLog, IVsActivityLog>())
    {
    }

    // Internal for testing.
    [SuppressMessage("RoslynDiagnosticsReliability", "RS0034: Exported parts should have a public constructor marked with 'ImportingConstructorAttribute'",
        Justification = "This is an internal constructor exposed for testing and delegated to by the public importing constructor")]
    internal SdkAnalyzerAssemblyRedirector(string? insertedAnalyzersDirectory, IVsActivityLog? log = null)
    {
        _log = log;
        var enable = Environment.GetEnvironmentVariable("DOTNET_ANALYZER_REDIRECTING");
        _enabled = !"0".Equals(enable, StringComparison.OrdinalIgnoreCase) && !"false".Equals(enable, StringComparison.OrdinalIgnoreCase);
        _insertedAnalyzersDirectory = insertedAnalyzersDirectory;
        _analyzerMap = CreateAnalyzerMap();
    }

    private ImmutableDictionary<string, List<AnalyzerInfo>> CreateAnalyzerMap()
    {
        if (!_enabled)
        {
            Log("Analyzer redirecting is disabled.");
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        var metadataFilePath = Path.Combine(_insertedAnalyzersDirectory, "metadata.json");
        if (!File.Exists(metadataFilePath))
        {
            Log($"File does not exist: {metadataFilePath}");
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        var versions = JsonSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllText(metadataFilePath));

Review comment (suggestion):
If we're not actually using the MEF component for testing, the better pattern might be to break the stuff needed for testing out to a separate class and then test that directly.

Code after:
[Export(typeof(IAnalyzerAssemblyRedirector))]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class SdkAnalyzerAssemblyRedirector(SVsServiceProvider serviceProvider) : SdkAnalyzerAssemblyRedirectorCore(
    GetInsertedAnalyzersDirectory(),
    (IVsActivityLog)serviceProvider.GetService(typeof(SVsActivityLog)))
{
    private static string? GetInsertedAnalyzersDirectory()
    {
        var enable = Environment.GetEnvironmentVariable("DOTNET_ANALYZER_REDIRECTING");
        if (!"0".Equals(enable, StringComparison.OrdinalIgnoreCase) && !"false".Equals(enable, StringComparison.OrdinalIgnoreCase))
        {
            return Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"CommonExtensions\Microsoft\DotNet"));
        }

        return null;
    }
}

/// <summary>
/// Core functionality of <see cref="SdkAnalyzerAssemblyRedirector"/> extracted for testing.
/// </summary>
internal class SdkAnalyzerAssemblyRedirectorCore : IAnalyzerAssemblyRedirector
{
    private readonly IVsActivityLog? _log;

    /// <summary>
    /// Map from analyzer assembly name (file name without extension) to a list of matching analyzers.
    /// </summary>
    private readonly Lazy<ImmutableDictionary<string, List<AnalyzerInfo>>> _analyzerMap;

    public SdkAnalyzerAssemblyRedirectorCore(string? insertedAnalyzersDirectory, IVsActivityLog? log = null)
    {
        _log = log;
        _analyzerMap = new(() => CreateAnalyzerMap(insertedAnalyzersDirectory));
    }

    private ImmutableDictionary<string, List<AnalyzerInfo>> CreateAnalyzerMap(string? insertedAnalyzersDirectory)
    {
        if (insertedAnalyzersDirectory == null)
        {
            Log("Analyzer redirecting is disabled.");
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        var metadataFilePath = Path.Combine(insertedAnalyzersDirectory, "metadata.json");
        if (!File.Exists(metadataFilePath))
        {
            Log($"File does not exist: {metadataFilePath}");
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }