< Summary

Information
Class: SwitchBlade.Services.IconService
Assembly: SwitchBlade
File(s): D:\a\switchblade\switchblade\Services\IconService.cs
Tag: 203_23722840422
Line coverage
100%
Covered lines: 21
Uncovered lines: 0
Coverable lines: 21
Total lines: 62
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%44100%
get_CacheCount()100%11100%
GetIcon(...)100%88100%
ClearCache()100%11100%

File(s)

D:\a\switchblade\switchblade\Services\IconService.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.Windows;
 4using System.Windows.Interop;
 5using System.Windows.Media;
 6using System.Windows.Media.Imaging;
 7using SwitchBlade.Contracts;
 8
 9namespace SwitchBlade.Services
 10{
 11    /// <summary>
 12    /// Extracts and caches application icons from executable files.
 13    /// Icons are cached by full executable path to handle different versions of same-named executables.
 14    /// </summary>
 15    public class IconService : IIconService
 16    {
 1317        private readonly ConcurrentDictionary<string, ImageSource?> _iconCache = new(StringComparer.OrdinalIgnoreCase);
 18        private readonly ISettingsService _settingsService;
 19        private readonly IIconExtractor _iconExtractor;
 20
 621        public int CacheCount => _iconCache.Count;
 22
 23        // Default to a safe limit if settings unavailable (though they should be)
 24        private const int FallbackMaxCacheSize = 200;
 25
 1326        public IconService(ISettingsService settingsService, IIconExtractor? iconExtractor = null)
 1327        {
 1328            _settingsService = settingsService ?? throw new ArgumentNullException(nameof(settingsService));
 1229            _iconExtractor = iconExtractor ?? new IconExtractor();
 1230        }
 31
 32        /// <summary>
 33        /// Gets the icon for the specified executable path.
 34        /// Uses a cache to avoid repeated extractions.
 35        /// </summary>
 36        public ImageSource? GetIcon(string? executablePath)
 1437        {
 1438            if (string.IsNullOrEmpty(executablePath))
 239                return null;
 40
 41            // Check cache size limit before adding new items
 1242            int limit = _settingsService.Settings?.IconCacheSize ?? FallbackMaxCacheSize;
 43
 44            // If cache is full and this is a new item, clear it to prevent unbounded growth
 1245            if (_iconCache.Count >= limit && !_iconCache.ContainsKey(executablePath))
 146            {
 147                _iconCache.Clear();
 148                Core.Logger.Log($"Icon cache limit ({limit}) reached. Cleared cache.");
 149            }
 50
 2151            return _iconCache.GetOrAdd(executablePath, path => _iconExtractor.ExtractIcon(path));
 1452        }
 53
 54        /// <summary>
 55        /// Clears the icon cache to free memory.
 56        /// </summary>
 57        public void ClearCache()
 158        {
 159            _iconCache.Clear();
 160        }
 61    }
 62}