Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorMatt Ward <matt.ward@xamarin.com>2017-07-14 21:52:06 +0300
committerMatt Ward <matt.ward@xamarin.com>2017-07-24 12:22:06 +0300
commite5ac3f424cda5e5c6dd8ffb12429709213563b14 (patch)
tree64694fde35692bb290b9334ad4b415e6d727d77a /main/src
parent209f8f0458941908f2e3e975fead90be1f16f870 (diff)
[NuGet] Fix transitive assembly references not available until restart
Fixed bug #58009 - Transitive assembly references not available until project reloaded https://bugzilla.xamarin.com/show_bug.cgi?id=58009 With a solution containing three .NET Standard projects: LibC references LibB which references LibA. If the Newtonsoft.Json NuGet package was installed into LibA the types from this NuGet packages are not available in LibB or LibC until the solution is closed and re-opened again. Closing and re-opening the solution refreshes the reference information for the type system. To fix this when a NuGet package is installed into a .NET Core project the projects that reference this project have their reference information refreshed by calling NotifyModified ("References") which causes the type system to get the reference information again from MSBuild. Types from the installed NuGet packages are then available in projects that reference this updated project either directly or indirectly.
Diffstat (limited to 'main/src')
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs2
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs122
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs186
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs12
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs78
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs8
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs28
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs2
-rw-r--r--main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedProjectSystem.cs2
9 files changed, 416 insertions, 24 deletions
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs
index b2a0de2557..4b9eaae8f3 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs
@@ -107,7 +107,7 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers
return Task.FromResult (0);
}
- public void NotifyProjectReferencesChanged ()
+ public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences)
{
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs
index d6cb64c80c..69135e9943 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs
@@ -50,13 +50,21 @@ namespace MonoDevelop.PackageManagement.Tests
void CreateNuGetProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj")
{
context = new FakeNuGetProjectContext ();
- dotNetProject = new DummyDotNetProject ();
- dotNetProject.Name = projectName;
- dotNetProject.FileName = fileName.ToNativePath ();
+ dotNetProject = CreateDotNetCoreProject (projectName, fileName);
+ var solution = new Solution ();
+ solution.RootFolder.AddItem (dotNetProject);
project = new TestableDotNetCoreNuGetProject (dotNetProject);
buildIntegratedRestorer = project.BuildIntegratedRestorer;
}
+ static DummyDotNetProject CreateDotNetCoreProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj")
+ {
+ var project = new DummyDotNetProject ();
+ project.Name = projectName;
+ project.FileName = fileName.ToNativePath ();
+ return project;
+ }
+
void AddDotNetProjectPackageReference (string packageId, string version)
{
var packageReference = ProjectPackageReference.Create (packageId, version);
@@ -302,8 +310,6 @@ namespace MonoDevelop.PackageManagement.Tests
{
CreateNuGetProject ();
AddDotNetProjectPackageReference ("NUnit", "2.6.0");
- var solution = new Solution ();
- solution.RootFolder.AddItem (dotNetProject);
string modifiedHint = null;
dotNetProject.Modified += (sender, e) => {
modifiedHint = e.Single ().Hint;
@@ -312,7 +318,8 @@ namespace MonoDevelop.PackageManagement.Tests
await project.PostProcessAsync (context, CancellationToken.None);
- Assert.AreEqual (solution, project.SolutionUsedToCreateBuildIntegratedRestorer);
+ Assert.IsNotNull (dotNetProject.ParentSolution);
+ Assert.AreEqual (dotNetProject.ParentSolution, project.SolutionUsedToCreateBuildIntegratedRestorer);
Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored);
Assert.AreEqual ("References", modifiedHint);
}
@@ -388,9 +395,110 @@ namespace MonoDevelop.PackageManagement.Tests
modifiedHint = e.Single ().Hint;
};
- project.NotifyProjectReferencesChanged ();
+ project.NotifyProjectReferencesChanged (false);
Assert.AreEqual ("References", modifiedHint);
}
+
+ /// <summary>
+ /// Assembly references are transitive for .NET Core projects so any .NET Core project
+ /// that references the project having a NuGet package being installed needs to refresh
+ /// references for the other projects not just itself.
+ /// </summary>
+ [Test]
+ public async Task PostProcessAsync_DotNetCoreProjectReferencesThisProject_NotifyReferencesChangedEventFiredForBothProjects ()
+ {
+ CreateNuGetProject ();
+ AddDotNetProjectPackageReference ("NUnit", "2.6.0");
+ var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj");
+ dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference);
+ var projectReference = ProjectReference.CreateProjectReference (dotNetProject);
+ dotNetProjectWithProjectReference.References.Add (projectReference);
+ string modifiedHintMainProject = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHintMainProject = e.Single ().Hint;
+ };
+ string modifiedHintProjectWithReference = null;
+ dotNetProjectWithProjectReference.Modified += (sender, e) => {
+ modifiedHintProjectWithReference = e.Single ().Hint;
+ };
+
+ await project.PostProcessAsync (context, CancellationToken.None);
+
+ Assert.AreEqual ("References", modifiedHintMainProject);
+ Assert.AreEqual ("References", modifiedHintProjectWithReference);
+ }
+
+ [Test]
+ public async Task PostProcessAsync_DotNetCoreProjectReferencesThisProjectLockFileNotChanged_NotifyReferencesChangedEventFiredForBothProjects ()
+ {
+ CreateNuGetProject ();
+ AddDotNetProjectPackageReference ("NUnit", "2.6.0");
+ var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj");
+ dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference);
+ var projectReference = ProjectReference.CreateProjectReference (dotNetProject);
+ dotNetProjectWithProjectReference.References.Add (projectReference);
+ string modifiedHintMainProject = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHintMainProject = e.Single ().Hint;
+ };
+ string modifiedHintProjectWithReference = null;
+ dotNetProjectWithProjectReference.Modified += (sender, e) => {
+ modifiedHintProjectWithReference = e.Single ().Hint;
+ };
+ OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install);
+
+ await project.PostProcessAsync (context, CancellationToken.None);
+
+ Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored);
+ Assert.AreEqual ("References", modifiedHintMainProject);
+ Assert.AreEqual ("References", modifiedHintProjectWithReference);
+ }
+
+ [Test]
+ public void NotifyProjectReferencesChanged_IncludeTransitiveReferences_NotifyReferencesChangedEventFiredForAllProjects ()
+ {
+ CreateNuGetProject ();
+ var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj");
+ dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference);
+ var projectReference = ProjectReference.CreateProjectReference (dotNetProject);
+ dotNetProjectWithProjectReference.References.Add (projectReference);
+ string modifiedHintMainProject = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHintMainProject = e.Single ().Hint;
+ };
+ string modifiedHintProjectWithReference = null;
+ dotNetProjectWithProjectReference.Modified += (sender, e) => {
+ modifiedHintProjectWithReference = e.Single ().Hint;
+ };
+
+ project.NotifyProjectReferencesChanged (true);
+
+ Assert.AreEqual ("References", modifiedHintMainProject);
+ Assert.AreEqual ("References", modifiedHintProjectWithReference);
+ }
+
+ [Test]
+ public void NotifyProjectReferencesChanged_DoNotIncludeTransitiveReferences_NotifyReferencesChangedEventFiredForMainProjectOnly ()
+ {
+ CreateNuGetProject ();
+ var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj");
+ dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference);
+ var projectReference = ProjectReference.CreateProjectReference (dotNetProject);
+ dotNetProjectWithProjectReference.References.Add (projectReference);
+ string modifiedHintMainProject = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHintMainProject = e.Single ().Hint;
+ };
+ string modifiedHintProjectWithReference = null;
+ dotNetProjectWithProjectReference.Modified += (sender, e) => {
+ modifiedHintProjectWithReference = e.Single ().Hint;
+ };
+
+ project.NotifyProjectReferencesChanged (false);
+
+ Assert.AreEqual ("References", modifiedHintMainProject);
+ Assert.IsNull (modifiedHintProjectWithReference);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
index c92c7b099b..959cba5504 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs
@@ -25,8 +25,9 @@
// THE SOFTWARE.
using System.Collections.Generic;
-using MonoDevelop.PackageManagement;
+using System.Linq;
using MonoDevelop.PackageManagement.Tests.Helpers;
+using MonoDevelop.Projects;
using NUnit.Framework;
namespace MonoDevelop.PackageManagement.Tests
@@ -56,6 +57,20 @@ namespace MonoDevelop.PackageManagement.Tests
existingFiles.Add (fileName.ToNativePath ());
}
+ static DummyDotNetProject CreateDotNetCoreProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj")
+ {
+ var project = new DummyDotNetProject ();
+ project.Name = projectName;
+ project.FileName = fileName.ToNativePath ();
+ return project;
+ }
+
+ void AddParentSolution (DotNetProject dotNetProject)
+ {
+ var solution = new Solution ();
+ solution.RootFolder.AddItem (dotNetProject);
+ }
+
[Test]
public void GetPackagesConfigFilePath_ProjectPackagesConfigFileDoesNotExist_ReturnsDefaultPackagesConfigFile ()
{
@@ -162,6 +177,175 @@ namespace MonoDevelop.PackageManagement.Tests
Assert.IsTrue (result);
}
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_NoProjectReferencesAllProjects_NotifyReferencesChangedForProject ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged (transitiveOnly: false);
+
+ Assert.AreEqual ("References", modifiedHint);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_NoProjectReferencesTransitiveProjectReferencesOnly_NotifyReferencesChangedNotFiredForProject ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged (transitiveOnly: true);
+
+ Assert.IsNull (modifiedHint);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_OneProjectReferencesProject_NotifyReferencesChangedForAllProjects ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject);
+ referencingProject.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject = null;
+ referencingProject.Modified += (sender, e) => {
+ modifiedHintForReferencingProject = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged ();
+
+ Assert.AreEqual ("References", modifiedHint);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_OneProjectReferencesProjectWithReferencedOutputAssemblyFalse_NotifyReferencesChangedNotFiredForReferencingProject ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject);
+ var projectReference = ProjectReference.CreateProjectReference (dotNetProject);
+ projectReference.ReferenceOutputAssembly = false;
+ referencingProject.References.Add (projectReference);
+ string modifiedHintForReferencingProject = null;
+ referencingProject.Modified += (sender, e) => {
+ modifiedHintForReferencingProject = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged (true);
+
+ Assert.IsNull (modifiedHintForReferencingProject);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_TwoOneProjectReferencesModifiedProject_NotifyReferencesChangedForAllProjects ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject1 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1);
+ referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ var referencingProject2 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2);
+ referencingProject2.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject1 = null;
+ referencingProject1.Modified += (sender, e) => {
+ modifiedHintForReferencingProject1 = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject2 = null;
+ referencingProject2.Modified += (sender, e) => {
+ modifiedHintForReferencingProject2 = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged ();
+
+ Assert.AreEqual ("References", modifiedHint);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject1);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject2);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_TwoOneProjectReferencesChainToModifiedProject_NotifyReferencesChangedForAllProjects ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject1 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1);
+ referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ var referencingProject2 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2);
+ referencingProject2.References.Add (ProjectReference.CreateProjectReference (referencingProject1));
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject1 = null;
+ referencingProject1.Modified += (sender, e) => {
+ modifiedHintForReferencingProject1 = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject2 = null;
+ referencingProject2.Modified += (sender, e) => {
+ modifiedHintForReferencingProject2 = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged ();
+
+ Assert.AreEqual ("References", modifiedHint);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject1);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject2);
+ }
+
+ /// <summary>
+ /// Same as above but the projects are added to the solution in a different order.
+ /// </summary>
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_TwoOneProjectReferencesChainToModifiedProject_NotifyReferencesChangedForAllProjects2 ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject1 = CreateDotNetCoreProject ();
+ var referencingProject2 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2);
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1);
+ referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ referencingProject2.References.Add (ProjectReference.CreateProjectReference (referencingProject1));
+ string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject1 = null;
+ referencingProject1.Modified += (sender, e) => {
+ modifiedHintForReferencingProject1 = e.First ().Hint;
+ };
+ string modifiedHintForReferencingProject2 = null;
+ referencingProject2.Modified += (sender, e) => {
+ modifiedHintForReferencingProject2 = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged ();
+
+ Assert.AreEqual ("References", modifiedHint);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject1);
+ Assert.AreEqual ("References", modifiedHintForReferencingProject2);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs
index 659798a1b2..c861d731d8 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs
@@ -281,7 +281,7 @@ namespace MonoDevelop.PackageManagement
}
Runtime.RunInMainThread (() => {
- DotNetProject.NotifyModified ("References");
+ DotNetProject.DotNetCoreNotifyReferencesChanged ();
});
packageManagementEvents.OnFileChanged (project.GetNuGetAssetsFilePath ());
@@ -303,7 +303,7 @@ namespace MonoDevelop.PackageManagement
if (!packageRestorer.LockFileChanged) {
// Need to refresh the references since the restore did not.
await Runtime.RunInMainThread (() => {
- DotNetProject.NotifyModified ("References");
+ DotNetProject.DotNetCoreNotifyReferencesChanged ();
packageManagementEvents.OnFileChanged (project.GetNuGetAssetsFilePath ());
});
}
@@ -326,12 +326,16 @@ namespace MonoDevelop.PackageManagement
restoreRequired = actions.Any (action => action.NuGetProjectActionType == NuGetProjectActionType.Install);
}
- public void NotifyProjectReferencesChanged ()
+ public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences)
{
Runtime.AssertMainThread ();
DotNetProject.RefreshProjectBuilder ();
- DotNetProject.NotifyModified ("References");
+
+ if (includeTransitiveProjectReferences)
+ DotNetProject.DotNetCoreNotifyReferencesChanged ();
+ else
+ DotNetProject.NotifyModified ("References");
}
/// <summary>
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
index fb79aee86b..9b5dc21dc3 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs
@@ -216,5 +216,83 @@ namespace MonoDevelop.PackageManagement
return File.Exists (propsFileName) &&
File.Exists (targetsFileName);
}
+
+ /// <summary>
+ /// If a NuGet package is installed into a .NET Core project then all .NET Core projects that
+ /// reference this project need to have their reference information updated. This allows the
+ /// assemblies from the NuGet package to be made available to the other projects since .NET
+ /// Core projects support transitive references. This method calls NotifyModified for each
+ /// project that references it, as well as for the project itself, passing the hint 'References'
+ /// which will cause the type system to refresh its reference information, which will be taken
+ /// from MSBuild.
+ ///
+ /// All projects that reference .NET Core projects will have their references refreshed. If a
+ /// .NET Framework project (non SDK), has PackageReferences and references a .NET Standard project
+ /// (SDK project) then NuGet dependencies from the .NET Standard project are available to the
+ /// .NET Framework project transitively without needing the NuGet package to be installed into
+ /// the .NET Framework project. So refreshing the references of any project that references a
+ /// .NET Core project will ensure assemblies from NuGet packages are available after installing
+ /// a new NuGet package into the referenced project.
+ /// </summary>
+ /// <param name="project">.NET Core project</param>
+ /// <param name="transitiveOnly">If false then the project passed will also have its
+ /// references refreshed. Otherwise only the projects that reference the project will
+ /// have their references refreshed.</param>
+ public static void DotNetCoreNotifyReferencesChanged (this DotNetProject project, bool transitiveOnly = false)
+ {
+ if (!transitiveOnly)
+ project.NotifyModified ("References");
+
+ var traversedProjects = new Dictionary<string, bool> ();
+ traversedProjects.Add (project.ItemId, true);
+
+ foreach (var currentProject in project.ParentSolution.GetAllDotNetProjects ()) {
+ if (!traversedProjects.ContainsKey (currentProject.ItemId))
+ DotNetCoreNotifyReferencesChanged (project, currentProject, traversedProjects);
+ }
+ }
+
+ static bool DotNetCoreNotifyReferencesChanged (
+ DotNetProject mainProject,
+ DotNetProject project,
+ Dictionary<string, bool> traversedProjects)
+ {
+ foreach (var projectReference in project.References.Where (IncludeProjectReference)) {
+ var resolvedProject = projectReference.ResolveProject (mainProject.ParentSolution) as DotNetProject;
+ if (resolvedProject == null)
+ continue;
+
+ if (resolvedProject == mainProject) {
+ traversedProjects [project.ItemId] = true;
+ project.NotifyModified ("References");
+ return true;
+ }
+
+ if (traversedProjects.TryGetValue (resolvedProject.ItemId, out bool referencesProject)) {
+ if (referencesProject) {
+ traversedProjects [project.ItemId] = referencesProject;
+ project.NotifyModified ("References");
+ return true;
+ }
+ continue;
+ }
+
+ if (DotNetCoreNotifyReferencesChanged (mainProject, resolvedProject, traversedProjects)) {
+ traversedProjects [project.ItemId] = true;
+ project.NotifyModified ("References");
+ return true;
+ }
+ }
+
+ traversedProjects [project.ItemId] = false;
+
+ return false;
+ }
+
+ static bool IncludeProjectReference (ProjectReference projectReference)
+ {
+ return projectReference.ReferenceType == ReferenceType.Project &&
+ projectReference.ReferenceOutputAssembly;
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs
index b14d19a7ba..666e49130f 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs
@@ -37,7 +37,13 @@ namespace MonoDevelop.PackageManagement
void OnBeforeUninstall (IEnumerable<NuGetProjectAction> actions);
void OnAfterExecuteActions (IEnumerable<NuGetProjectAction> actions);
Task PostProcessAsync (INuGetProjectContext nuGetProjectContext, CancellationToken token);
- void NotifyProjectReferencesChanged ();
+
+ /// <summary>
+ /// Notifies the project references changed.
+ /// </summary>
+ /// <param name="includeTransitiveProjectReferences">If set to <c>true</c> also notify references
+ /// have changed in all projects that transitively reference this project.</param>
+ void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences);
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs
index 86aafc4c9a..21cf4da934 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs
@@ -98,8 +98,10 @@ namespace MonoDevelop.PackageManagement
LockFileChanged = true;
await Runtime.RunInMainThread (() => {
FileService.NotifyFilesChanged (changedLocks);
- foreach (var project in affectedProjects) {
- NotifyProjectReferencesChanged (project);
+ foreach (var project in affectedProjects) {
+ // Restoring the entire solution so do not refresh references for
+ // transitive project references since they should be refreshed anyway.
+ NotifyProjectReferencesChanged (project, includeTransitiveProjectReferences: false);
}
});
}
@@ -114,12 +116,17 @@ namespace MonoDevelop.PackageManagement
var changedLock = await RestorePackagesInternal (project, cancellationToken);
if (projectToReload != null) {
- await ReloadProject (projectToReload, changedLock);
+ // Need to ensure transitive project references are refreshed if only the single
+ // project is reloaded since they will still be out of date.
+ await ReloadProject (projectToReload, changedLock, refreshTransitiveReferences: true);
} else if (changedLock != null) {
LockFileChanged = true;
await Runtime.RunInMainThread (() => {
- FileService.NotifyFileChanged (changedLock);
- NotifyProjectReferencesChanged (project);
+ FileService.NotifyFileChanged (changedLock);
+
+ // Restoring a single project so ensure references are refreshed for
+ // transitive project references.
+ NotifyProjectReferencesChanged (project, includeTransitiveProjectReferences: true);
});
}
}
@@ -153,11 +160,13 @@ namespace MonoDevelop.PackageManagement
return null;
}
- static void NotifyProjectReferencesChanged (BuildIntegratedNuGetProject project)
+ static void NotifyProjectReferencesChanged (
+ BuildIntegratedNuGetProject project,
+ bool includeTransitiveProjectReferences)
{
var buildIntegratedProject = project as IBuildIntegratedNuGetProject;
if (buildIntegratedProject != null) {
- buildIntegratedProject.NotifyProjectReferencesChanged ();
+ buildIntegratedProject.NotifyProjectReferencesChanged (includeTransitiveProjectReferences);
}
}
@@ -219,7 +228,7 @@ namespace MonoDevelop.PackageManagement
return null;
}
- Task ReloadProject (DotNetProject projectToReload, string changedLock)
+ Task ReloadProject (DotNetProject projectToReload, string changedLock, bool refreshTransitiveReferences = false)
{
return Runtime.RunInMainThread (async () => {
if (changedLock != null) {
@@ -227,6 +236,9 @@ namespace MonoDevelop.PackageManagement
FileService.NotifyFileChanged (changedLock);
}
await projectToReload.ReevaluateProject (new ProgressMonitor ());
+
+ if (refreshTransitiveReferences)
+ projectToReload.DotNetCoreNotifyReferencesChanged (transitiveOnly: true);
});
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs
index 5caaec2673..a85f52f17f 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs
@@ -284,7 +284,7 @@ namespace MonoDevelop.PackageManagement
{
}
- public void NotifyProjectReferencesChanged ()
+ public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences)
{
Runtime.AssertMainThread ();
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedProjectSystem.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedProjectSystem.cs
index 36f92f4490..1ea10e4766 100644
--- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedProjectSystem.cs
+++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedProjectSystem.cs
@@ -247,7 +247,7 @@ namespace MonoDevelop.PackageManagement
return excludedReferences;
}
- public void NotifyProjectReferencesChanged ()
+ public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences)
{
Runtime.AssertMainThread ();