Description
ProjectTagViolationDetector.GetViolationsFrom() calls this.projectTagProvider.GetProjectTag(referenceContext.Reference) inside a nested loop (for each rule × each reference). ProjectTagProvider.GetProjectTag() loads and parses the XML project file from disk on every call.
Affected Files
src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs (line ~30, inside nested loop)
src/ReferenceCop/Providers/ProjectTagProvider.cs (entire GetProjectTag method — XDocument.Load() per call)
Impact
For a solution with R rules and N project references:
- R × N file I/O operations and XML parses, even though the same project files are read repeatedly
- For a typical solution (e.g., 20 rules, 50 references), this means 1,000 XML file parses per build, most of them redundant
- Build-time analyzer, so this directly impacts developer inner loop
Suggested Optimization
Cache the project tag per file path:
public class ProjectTagProvider : IProjectTagProvider
{
private readonly ConcurrentDictionary<string, string> _cache = new();
public string GetProjectTag(string projectFilePath)
{
return _cache.GetOrAdd(projectFilePath, path =>
{
if (!File.Exists(path)) return UnknownProjectTag;
var projectFile = XDocument.Load(path);
return projectFile
.Descendants(PropertyGroupNode)
.Elements(ProjectTagNode)
.FirstOrDefault()?.Value ?? UnknownProjectTag;
});
}
}
This reduces N×R file reads to at most N (one per unique project file), typically much fewer.
Description
ProjectTagViolationDetector.GetViolationsFrom()callsthis.projectTagProvider.GetProjectTag(referenceContext.Reference)inside a nested loop (for each rule × each reference).ProjectTagProvider.GetProjectTag()loads and parses the XML project file from disk on every call.Affected Files
src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs(line ~30, inside nested loop)src/ReferenceCop/Providers/ProjectTagProvider.cs(entireGetProjectTagmethod —XDocument.Load()per call)Impact
For a solution with R rules and N project references:
Suggested Optimization
Cache the project tag per file path:
This reduces N×R file reads to at most N (one per unique project file), typically much fewer.