Fix duplicate dependency issue (#2597)
* Fix duplicate dependency issue If a package has the same name as a framework assembly in the dependency graph, we usually replace it with the framework assembly if the package provides no assets. If the framework assembly wasn't resolved, it would skip this logic and end up adding dupes to the list, which blows up later on. This is a tactical fix to solve the issue, we need to do some more thinking to determine how we want to resolve conflicts between framework assemblies, packages and dlls with the same name.
This commit is contained in:
parent
8313400465
commit
4af795b9e8
5 changed files with 62 additions and 14 deletions
|
@ -0,0 +1,10 @@
|
|||
namespace TestMicrosoftCSharpReference
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"version": "1.0.0",
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"imports": "dnxcore50",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": "1.0.0-rc2-*"
|
||||
}
|
||||
},
|
||||
"net99": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.0.1-rc2-24018"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
public override IEnumerable<LockFileItem> CompileTimeAssemblies => FilterPlaceholders(base.CompileTimeAssemblies);
|
||||
|
||||
public bool HasCompileTimePlaceholder => base.CompileTimeAssemblies.Any(a => PackageDependencyProvider.IsPlaceholderFile(a));
|
||||
|
||||
private static IEnumerable<LockFileItem> FilterPlaceholders(IEnumerable<LockFileItem> items)
|
||||
{
|
||||
return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a));
|
||||
|
|
|
@ -377,22 +377,28 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
// To make them work seamlessly on those platforms, we fill the gap with a reference
|
||||
// assembly (if available)
|
||||
var package = library as PackageDescription;
|
||||
if (package != null && package.Resolved && !package.CompileTimeAssemblies.Any())
|
||||
if (package != null &&
|
||||
package.Resolved &&
|
||||
package.HasCompileTimePlaceholder &&
|
||||
!TargetFramework.IsPackageBased)
|
||||
{
|
||||
var replacement = referenceAssemblyDependencyResolver.GetDescription(new LibraryRange(library.Identity.Name, LibraryType.ReferenceAssembly), TargetFramework);
|
||||
if (replacement?.Resolved == true)
|
||||
var newKey = new LibraryKey(library.Identity.Name, LibraryType.ReferenceAssembly);
|
||||
var dependency = new LibraryRange(library.Identity.Name, LibraryType.ReferenceAssembly);
|
||||
|
||||
// If the framework assembly can't be resolved then mark it as unresolved but still replace the package
|
||||
// dependency
|
||||
var replacement = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
||||
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||
|
||||
requiresFrameworkAssemblies = true;
|
||||
|
||||
// Remove the original package reference
|
||||
libraries.Remove(pair.Key);
|
||||
|
||||
// Insert a reference assembly key if there isn't one
|
||||
if (!libraries.ContainsKey(newKey))
|
||||
{
|
||||
requiresFrameworkAssemblies = true;
|
||||
|
||||
// Remove the original package reference
|
||||
libraries.Remove(pair.Key);
|
||||
|
||||
// Insert a reference assembly key if there isn't one
|
||||
var key = new LibraryKey(replacement.Identity.Name, LibraryType.ReferenceAssembly);
|
||||
if (!libraries.ContainsKey(key))
|
||||
{
|
||||
libraries[key] = replacement;
|
||||
}
|
||||
libraries[newKey] = replacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,5 +65,18 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
|
||||
Assert.Equal(4, context.RootProject.Dependencies.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoDuplicateReferencesWhenFrameworkMissing()
|
||||
{
|
||||
var instance = TestAssetsManager.CreateTestInstance("TestMicrosoftCSharpReferenceMissingFramework")
|
||||
.WithLockFiles();
|
||||
|
||||
var context = new ProjectContextBuilder().WithProjectDirectory(instance.TestRoot)
|
||||
.WithTargetFramework("net99")
|
||||
.Build();
|
||||
|
||||
context.LibraryManager.GetLibraries().ToDictionary(l => l.Identity.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue