Skip to content

Commit 93d14ae

Browse files
committed
Remove Microsoft.Extensions.DependencyModel from Mvc.Core
1 parent 626137c commit 93d14ae

11 files changed

+142
-94
lines changed

src/Mvc/Mvc.Core/src/ApplicationParts/ApplicationPartAttribute.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,29 @@
55

66
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
77
{
8+
/// <summary>
9+
/// Specifies an assembly to be added as an <see cref="ApplicationPart" />.
10+
/// <para>
11+
/// In the ordinary case, MVC will generate <see cref="ApplicationPartAttribute" />
12+
/// instances on the entry assembly for each dependency that references MVC.
13+
/// Each of these assemblies is treated as an <see cref="ApplicationPart" />.
14+
/// </para>
15+
/// </summary>
816
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
917
public sealed class ApplicationPartAttribute : Attribute
1018
{
19+
/// <summary>
20+
/// Initializes a new instance of <see cref="ApplicationPartAttribute" />.
21+
/// </summary>
22+
/// <param name="assemblyName">The assembly name.</param>
1123
public ApplicationPartAttribute(string assemblyName)
1224
{
13-
AssemblyName = assemblyName;
25+
AssemblyName = assemblyName ?? throw new ArgumentNullException(nameof(assemblyName));
1426
}
1527

16-
public string AssemblyName { get; private set; }
28+
/// <summary>
29+
/// Gets the assembly name.
30+
/// </summary>
31+
public string AssemblyName { get; }
1732
}
1833
}

src/Mvc/Mvc.Core/src/ApplicationParts/ApplicationPartManager.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,9 @@ internal void PopulateDefaultParts(string entryAssemblyName)
6060
{
6161
if (!seenAssemblies.Add(assembly))
6262
{
63-
// Assembly discovery may be duplicated (e.g. if a user explicitly specified an ApplicationPartAAttribute
64-
// that was also codegened), but we do not want duplicate ApplicationParts.
65-
// Avoid duplicates. Note that we prefer doing this over Distinct since the latter isn't
66-
// guaranteed to preserve the original ordering which is important here.
63+
// "assemblies" may contain duplicate values, but we want unique ApplicationPart instances.
64+
// Note that we prefer using a HashSet over Distinct since the latter isn't
65+
// guaranteed to preserve the original ordering.
6766
continue;
6867
}
6968

src/Mvc/Mvc.Core/src/ApplicationParts/AssemblyPart.cs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using System.Reflection;
8-
using Microsoft.Extensions.DependencyModel;
98

109
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
1110
{
1211
/// <summary>
1312
/// An <see cref="ApplicationPart"/> backed by an <see cref="System.Reflection.Assembly"/>.
1413
/// </summary>
15-
public class AssemblyPart :
16-
ApplicationPart,
17-
IApplicationPartTypeProvider,
18-
ICompilationReferencesProvider
14+
public class AssemblyPart : ApplicationPart, IApplicationPartTypeProvider
1915
{
2016
/// <summary>
2117
/// Initializes a new <see cref="AssemblyPart"/> instance.
@@ -39,27 +35,6 @@ public AssemblyPart(Assembly assembly)
3935
/// <inheritdoc />
4036
public IEnumerable<TypeInfo> Types => Assembly.DefinedTypes;
4137

42-
/// <inheritdoc />
43-
public IEnumerable<string> GetReferencePaths()
44-
{
45-
if (Assembly.IsDynamic)
46-
{
47-
// Skip loading process for dynamic assemblies. This prevents DependencyContextLoader from reading the
48-
// .deps.json file from either manifest resources or the assembly location, which will fail.
49-
return Enumerable.Empty<string>();
50-
}
51-
52-
var dependencyContext = DependencyContext.Load(Assembly);
53-
if (dependencyContext != null)
54-
{
55-
return dependencyContext.CompileLibraries.SelectMany(library => library.ResolveReferencePaths());
56-
}
57-
58-
// If an application has been compiled without preserveCompilationContext, return the path to the assembly
59-
// as a reference. For runtime compilation, this will allow the compilation to succeed as long as it least
60-
// one application part has been compiled with preserveCompilationContext and contains a super set of types
61-
// required for the compilation to succeed.
62-
return new[] { Assembly.Location };
63-
}
38+
6439
}
6540
}

src/Mvc/Mvc.Core/src/Microsoft.AspNetCore.Mvc.Core.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ Microsoft.AspNetCore.Mvc.RouteAttribute</Description>
4242
<Reference Include="Microsoft.AspNetCore.Routing.Abstractions" />
4343
<Reference Include="Microsoft.AspNetCore.Routing" />
4444
<Reference Include="Microsoft.Extensions.DependencyInjection" />
45-
<Reference Include="Microsoft.Extensions.DependencyModel" />
4645
<Reference Include="Microsoft.Extensions.FileProviders.Abstractions" />
4746
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
4847
</ItemGroup>

src/Mvc/Mvc.Core/test/ApplicationParts/AssemblyPartTest.cs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -50,55 +50,5 @@ public void AssemblyPart_Assembly_ReturnsAssembly()
5050
// Act & Assert
5151
Assert.Equal(part.Assembly, assembly);
5252
}
53-
54-
[Fact]
55-
public void GetReferencePaths_ReturnsReferencesFromDependencyContext_IfPreserveCompilationContextIsSet()
56-
{
57-
// Arrange
58-
var assembly = GetType().GetTypeInfo().Assembly;
59-
var part = new AssemblyPart(assembly);
60-
61-
// Act
62-
var references = part.GetReferencePaths().ToList();
63-
64-
// Assert
65-
Assert.Contains(assembly.Location, references);
66-
Assert.Contains(
67-
typeof(AssemblyPart).GetTypeInfo().Assembly.GetName().Name,
68-
references.Select(Path.GetFileNameWithoutExtension));
69-
}
70-
71-
[Fact]
72-
public void GetReferencePaths_ReturnsAssemblyLocation_IfPreserveCompilationContextIsNotSet()
73-
{
74-
// Arrange
75-
// src projects do not have preserveCompilationContext specified.
76-
var assembly = typeof(AssemblyPart).GetTypeInfo().Assembly;
77-
var part = new AssemblyPart(assembly);
78-
79-
// Act
80-
var references = part.GetReferencePaths().ToList();
81-
82-
// Assert
83-
var actual = Assert.Single(references);
84-
Assert.Equal(assembly.Location, actual);
85-
}
86-
87-
[Fact]
88-
public void GetReferencePaths_ReturnsEmptySequenceForDynamicAssembly()
89-
{
90-
// Arrange
91-
var name = new AssemblyName($"DynamicAssembly-{Guid.NewGuid()}");
92-
var assembly = AssemblyBuilder.DefineDynamicAssembly(name,
93-
AssemblyBuilderAccess.RunAndCollect);
94-
95-
var part = new AssemblyPart(assembly);
96-
97-
// Act
98-
var references = part.GetReferencePaths().ToList();
99-
100-
// Assert
101-
Assert.Empty(references);
102-
}
10353
}
10454
}

src/Mvc/Mvc.Core/test/Microsoft.AspNetCore.Mvc.Core.Test.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.0</TargetFramework>
5-
<PreserveCompilationContext>true</PreserveCompilationContext>
65
</PropertyGroup>
76

87
<ItemGroup>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.Extensions.DependencyModel;
8+
9+
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
10+
{
11+
public static class AssemblyPartExtensions
12+
{
13+
/// <inheritdoc />
14+
public static IEnumerable<string> GetReferencePaths(this AssemblyPart assemblyPart)
15+
{
16+
var assembly = assemblyPart?.Assembly ?? throw new ArgumentNullException(nameof(assemblyPart));
17+
18+
if (assembly.IsDynamic)
19+
{
20+
// Skip loading process for dynamic assemblies. This prevents DependencyContextLoader from reading the
21+
// .deps.json file from either manifest resources or the assembly location, which will fail.
22+
return Enumerable.Empty<string>();
23+
}
24+
25+
var dependencyContext = DependencyContext.Load(assembly);
26+
if (dependencyContext != null)
27+
{
28+
return dependencyContext.CompileLibraries.SelectMany(library => library.ResolveReferencePaths());
29+
}
30+
31+
// If an application has been compiled without preserveCompilationContext, return the path to the assembly
32+
// as a reference. For runtime compilation, this will allow the compilation to succeed as long as it least
33+
// one application part has been compiled with preserveCompilationContext and contains a super set of types
34+
// required for the compilation to succeed.
35+
return new[] { assembly.Location };
36+
}
37+
}
38+
}

src/Mvc/Mvc.Razor.RuntimeCompilation/src/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<Reference Include="Microsoft.AspNetCore.Mvc.RazorPages" />
1515
<Reference Include="Microsoft.AspNetCore.Razor.Runtime" />
1616
<Reference Include="Microsoft.CodeAnalysis.Razor" />
17+
<Reference Include="Microsoft.Extensions.DependencyModel" />
1718
</ItemGroup>
1819

1920
<ItemGroup>

src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
using System;
54
using System.Collections.Generic;
65
using System.IO;
76
using System.Linq;
@@ -53,14 +52,21 @@ private IReadOnlyList<MetadataReference> GetCompilationReferences()
5352
// For unit testing
5453
internal IEnumerable<string> GetReferencePaths()
5554
{
56-
var referencesFromApplicationParts = _partManager
57-
.ApplicationParts
58-
.OfType<ICompilationReferencesProvider>()
59-
.SelectMany(part => part.GetReferencePaths());
55+
var referencePaths = new List<string>();
6056

61-
var referencePaths = referencesFromApplicationParts
62-
.Concat(_options.AdditionalReferencePaths)
63-
.Distinct(StringComparer.OrdinalIgnoreCase);
57+
foreach (var part in _partManager.ApplicationParts)
58+
{
59+
if (part is ICompilationReferencesProvider compilationReferenceProvider)
60+
{
61+
referencePaths.AddRange(compilationReferenceProvider.GetReferencePaths());
62+
}
63+
else if (part is AssemblyPart assemblyPart)
64+
{
65+
referencePaths.AddRange(assemblyPart.GetReferencePaths());
66+
}
67+
}
68+
69+
referencePaths.AddRange(_options.AdditionalReferencePaths);
6470

6571
return referencePaths;
6672
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Reflection;
8+
using System.Reflection.Emit;
9+
using Xunit;
10+
11+
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
12+
{
13+
public class AssemblyPartExtensionTest
14+
{
15+
[Fact]
16+
public void GetReferencePaths_ReturnsReferencesFromDependencyContext_IfPreserveCompilationContextIsSet()
17+
{
18+
// Arrange
19+
var assembly = GetType().GetTypeInfo().Assembly;
20+
var part = new AssemblyPart(assembly);
21+
22+
// Act
23+
var references = part.GetReferencePaths().ToList();
24+
25+
// Assert
26+
Assert.Contains(assembly.Location, references);
27+
Assert.Contains(
28+
typeof(AssemblyPart).GetTypeInfo().Assembly.GetName().Name,
29+
references.Select(Path.GetFileNameWithoutExtension));
30+
}
31+
32+
[Fact]
33+
public void GetReferencePaths_ReturnsAssemblyLocation_IfPreserveCompilationContextIsNotSet()
34+
{
35+
// Arrange
36+
// src projects do not have preserveCompilationContext specified.
37+
var assembly = typeof(AssemblyPart).GetTypeInfo().Assembly;
38+
var part = new AssemblyPart(assembly);
39+
40+
// Act
41+
var references = part.GetReferencePaths().ToList();
42+
43+
// Assert
44+
var actual = Assert.Single(references);
45+
Assert.Equal(assembly.Location, actual);
46+
}
47+
48+
[Fact]
49+
public void GetReferencePaths_ReturnsEmptySequenceForDynamicAssembly()
50+
{
51+
// Arrange
52+
var name = new AssemblyName($"DynamicAssembly-{Guid.NewGuid()}");
53+
var assembly = AssemblyBuilder.DefineDynamicAssembly(name,
54+
AssemblyBuilderAccess.RunAndCollect);
55+
56+
var part = new AssemblyPart(assembly);
57+
58+
// Act
59+
var references = part.GetReferencePaths().ToList();
60+
61+
// Assert
62+
Assert.Empty(references);
63+
}
64+
}
65+
}

src/Mvc/Mvc.Testing/src/Microsoft.AspNetCore.Mvc.Testing.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<Reference Include="Microsoft.AspNetCore.TestHost" />
1414
<Reference Include="Microsoft.AspNetCore.Mvc.Core" />
1515
<Reference Include="Microsoft.Extensions.HostFactoryResolver.Sources" />
16+
<Reference Include="Microsoft.Extensions.DependencyModel" />
1617
<Reference Include="Microsoft.Extensions.Hosting" />
1718
</ItemGroup>
1819

0 commit comments

Comments
 (0)