diff --git a/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs b/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs
index 6710d5c..3f8ddaa 100644
--- a/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs
+++ b/src/ReferenceCop.MSBuild/Providers/MSBuildProjectMetadataProvider.cs
@@ -1,5 +1,6 @@
namespace ReferenceCop.MSBuild
{
+ using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Build.Evaluation;
@@ -7,11 +8,22 @@ namespace ReferenceCop.MSBuild
///
/// Provides project reference information using MSBuild project evaluation.
///
- public class MSBuildProjectMetadataProvider : IProjectMetadataProvider
+ public class MSBuildProjectMetadataProvider : IProjectMetadataProvider, IDisposable
{
private const string ProjectReferenceNode = "ProjectReference";
private const string NoWarnMetadata = "NoWarn";
+ private readonly ProjectCollection projectCollection;
+ private bool disposed;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MSBuildProjectMetadataProvider()
+ {
+ this.projectCollection = new ProjectCollection();
+ }
+
///
/// Gets the project references from a project file.
///
@@ -19,8 +31,7 @@ public class MSBuildProjectMetadataProvider : IProjectMetadataProvider
/// The collection of project references.
public IEnumerable GetProjectReferences(string projectFilePath)
{
- var projectCollection = new ProjectCollection();
- var project = projectCollection.LoadProject(projectFilePath);
+ var project = this.LoadOrGetProject(projectFilePath);
// Get all ProjectReference items. These are the direct project references.
var projectReferences = project.GetItems(ProjectReferenceNode);
@@ -47,11 +58,48 @@ public IEnumerable GetProjectReferences(string projectFile
/// The resolved property value.
public string GetPropertyValue(string projectFilePath, string propertyName)
{
- var projectCollection = new ProjectCollection();
- var project = projectCollection.LoadProject(projectFilePath);
+ var project = this.LoadOrGetProject(projectFilePath);
project.ReevaluateIfNecessary();
return project.GetPropertyValue(propertyName);
}
+
+ ///
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases the resources used by the .
+ ///
+ /// Whether managed resources should be disposed.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!this.disposed)
+ {
+ if (disposing)
+ {
+ this.projectCollection.UnloadAllProjects();
+ this.projectCollection.Dispose();
+ }
+
+ this.disposed = true;
+ }
+ }
+
+ private Project LoadOrGetProject(string projectFilePath)
+ {
+ var fullPath = System.IO.Path.GetFullPath(projectFilePath);
+ var loaded = this.projectCollection.GetLoadedProjects(fullPath);
+
+ if (loaded.Count > 0)
+ {
+ return loaded.First();
+ }
+
+ return this.projectCollection.LoadProject(fullPath);
+ }
}
}
diff --git a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs
index d370247..d94d9aa 100644
--- a/src/ReferenceCop.MSBuild/ReferenceCopTask.cs
+++ b/src/ReferenceCop.MSBuild/ReferenceCopTask.cs
@@ -120,6 +120,10 @@ public bool Execute()
success = false;
this.BuildEngine.LogErrorEvent(ex);
}
+ finally
+ {
+ (this.projectReferencesProvider as IDisposable)?.Dispose();
+ }
return success;
}