diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template
index ef63096e8019c0..64a3e93967a3de 100644
--- a/eng/testing/linker/project.csproj.template
+++ b/eng/testing/linker/project.csproj.template
@@ -9,6 +9,10 @@
<_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs)
+
+ {AdditionalProjectReferences}
+
+
diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets
index 3729bd306bca94..6d89002d9e0c6a 100644
--- a/eng/testing/linker/trimmingTests.targets
+++ b/eng/testing/linker/trimmingTests.targets
@@ -57,6 +57,15 @@
<_projectSourceFile>%(TestConsoleApps.ProjectCompileItems)
+
+ <_additionalProjectReferenceTemp Include="$(AdditionalProjectReferences)" />
+ <_additionalProjectReference Include="<ProjectReference Include="$(LibrariesProjectRoot)%(_additionalProjectReferenceTemp.Identity)\src\%(_additionalProjectReferenceTemp.Identity).csproj" SkipUseReferenceAssembly="true" />" />
+
+
+
+ <_additionalProjectReferencesString>@(_additionalProjectReference, '%0a')
+
+
<_additionalProjectSourceFiles Include="%(TestConsoleApps.AdditionalSourceFiles)" />
@@ -69,7 +78,8 @@
.Replace('{TargetingPackDir}','$(MicrosoftNetCoreAppRefPackDir)')
.Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)')
.Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)')
- .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)'))"
+ .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)')
+ .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)'))"
Overwrite="true" />
diff --git a/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs b/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs
index 7f5b6c3aa0a529..574fd893febaae 100644
--- a/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs
+++ b/src/libraries/Common/src/Extensions/ActivatorUtilities/ActivatorUtilities.cs
@@ -40,7 +40,10 @@ static class ActivatorUtilities
/// The type to activate
/// Constructor arguments not provided by the .
/// An activated object of type instanceType
- public static object CreateInstance(IServiceProvider provider, Type instanceType, params object[] parameters)
+ public static object CreateInstance(
+ IServiceProvider provider,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType,
+ params object[] parameters)
{
int bestLength = -1;
bool seenPreferred = false;
@@ -49,11 +52,9 @@ public static object CreateInstance(IServiceProvider provider, Type instanceType
if (!instanceType.GetTypeInfo().IsAbstract)
{
- foreach (ConstructorInfo? constructor in instanceType
- .GetTypeInfo()
- .DeclaredConstructors)
+ foreach (ConstructorInfo? constructor in instanceType.GetConstructors())
{
- if (!constructor.IsStatic && constructor.IsPublic)
+ if (!constructor.IsStatic)
{
var matcher = new ConstructorMatcher(constructor);
bool isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false);
@@ -104,7 +105,9 @@ public static object CreateInstance(IServiceProvider provider, Type instanceType
/// A factory that will instantiate instanceType using an
/// and an argument array containing objects matching the types defined in argumentTypes
///
- public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentTypes)
+ public static ObjectFactory CreateFactory(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType,
+ Type[] argumentTypes)
{
FindApplicableConstructor(instanceType, argumentTypes, out ConstructorInfo? constructor, out int?[]? parameterMap);
@@ -126,19 +129,18 @@ public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentType
/// The service provider used to resolve dependencies
/// Constructor arguments not provided by the .
/// An activated object of type T
- public static T CreateInstance(IServiceProvider provider, params object[] parameters)
+ public static T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider, params object[] parameters)
{
return (T)CreateInstance(provider, typeof(T), parameters);
}
-
///
/// Retrieve an instance of the given type from the service provider. If one is not found then instantiate it directly.
///
/// The type of the service
/// The service provider used to resolve dependencies
/// The resolved service or created instance
- public static T GetServiceOrCreateInstance(IServiceProvider provider)
+ public static T GetServiceOrCreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider)
{
return (T)GetServiceOrCreateInstance(provider, typeof(T));
}
@@ -149,7 +151,9 @@ public static T GetServiceOrCreateInstance(IServiceProvider provider)
/// The service provider
/// The type of the service
/// The resolved service or created instance
- public static object GetServiceOrCreateInstance(IServiceProvider provider, Type type)
+ public static object GetServiceOrCreateInstance(
+ IServiceProvider provider,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
{
return provider.GetService(type) ?? CreateInstance(provider, type);
}
@@ -214,7 +218,7 @@ private static Expression BuildFactoryExpression(
}
private static void FindApplicableConstructor(
- Type instanceType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType,
Type[] argumentTypes,
out ConstructorInfo matchingConstructor,
out int?[] matchingParameterMap)
@@ -235,14 +239,14 @@ private static void FindApplicableConstructor(
// Tries to find constructor based on provided argument types
private static bool TryFindMatchingConstructor(
- Type instanceType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType,
Type[] argumentTypes,
[NotNullWhen(true)] ref ConstructorInfo? matchingConstructor,
[NotNullWhen(true)] ref int?[]? parameterMap)
{
- foreach (ConstructorInfo? constructor in instanceType.GetTypeInfo().DeclaredConstructors)
+ foreach (ConstructorInfo? constructor in instanceType.GetConstructors())
{
- if (constructor.IsStatic || !constructor.IsPublic)
+ if (constructor.IsStatic)
{
continue;
}
@@ -270,15 +274,15 @@ private static bool TryFindMatchingConstructor(
// Tries to find constructor marked with ActivatorUtilitiesConstructorAttribute
private static bool TryFindPreferredConstructor(
- Type instanceType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType,
Type[] argumentTypes,
[NotNullWhen(true)] ref ConstructorInfo? matchingConstructor,
[NotNullWhen(true)] ref int?[]? parameterMap)
{
bool seenPreferred = false;
- foreach (ConstructorInfo? constructor in instanceType.GetTypeInfo().DeclaredConstructors)
+ foreach (ConstructorInfo? constructor in instanceType.GetConstructors())
{
- if (constructor.IsStatic || !constructor.IsPublic)
+ if (constructor.IsStatic)
{
continue;
}
diff --git a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs
index 03f1b26ec0e233..45e8a6aea1d0b7 100644
--- a/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs
+++ b/src/libraries/Common/src/Extensions/ParameterDefaultValue/ParameterDefaultValue.cs
@@ -4,6 +4,7 @@
#nullable enable
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace Microsoft.Extensions.Internal
@@ -41,9 +42,13 @@ public static bool TryGetDefaultValue(ParameterInfo parameter, out object? defau
// Workaround for https://github.com/dotnet/corefx/issues/11797
if (defaultValue == null && parameter.ParameterType.IsValueType)
{
- defaultValue = Activator.CreateInstance(parameter.ParameterType);
+ defaultValue = CreateValueType(parameter.ParameterType);
}
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
+ Justification = "CreateInstance is only called on a ValueType, which will always have a default constructor.")]
+ object? CreateValueType(Type t) => Activator.CreateInstance(t);
+
// Handle nullable enums
if (defaultValue != null &&
parameter.ParameterType.IsGenericType &&
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs
index ad5be9396bf955..b1d8704fe0cbad 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Microsoft.Extensions.DependencyInjection.Extensions
@@ -124,7 +125,7 @@ public static void TryAdd(
/// The type of the service to register.
public static void TryAddTransient(
this IServiceCollection collection,
- Type service)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
{
if (collection == null)
{
@@ -151,7 +152,7 @@ public static void TryAddTransient(
public static void TryAddTransient(
this IServiceCollection collection,
Type service,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (collection == null)
{
@@ -210,7 +211,7 @@ public static void TryAddTransient(
///
/// The type of the service to add.
/// The .
- public static void TryAddTransient(this IServiceCollection collection)
+ public static void TryAddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection)
where TService : class
{
if (collection == null)
@@ -229,7 +230,7 @@ public static void TryAddTransient(this IServiceCollection collection)
/// The type of the service to add.
/// The type of the implementation to use.
/// The .
- public static void TryAddTransient(this IServiceCollection collection)
+ public static void TryAddTransient(this IServiceCollection collection)
where TService : class
where TImplementation : class, TService
{
@@ -265,7 +266,7 @@ public static void TryAddTransient(
/// The type of the service to register.
public static void TryAddScoped(
this IServiceCollection collection,
- Type service)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
{
if (collection == null)
{
@@ -292,7 +293,7 @@ public static void TryAddScoped(
public static void TryAddScoped(
this IServiceCollection collection,
Type service,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (collection == null)
{
@@ -351,7 +352,7 @@ public static void TryAddScoped(
///
/// The type of the service to add.
/// The .
- public static void TryAddScoped(this IServiceCollection collection)
+ public static void TryAddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection)
where TService : class
{
if (collection == null)
@@ -370,7 +371,7 @@ public static void TryAddScoped(this IServiceCollection collection)
/// The type of the service to add.
/// The type of the implementation to use.
/// The .
- public static void TryAddScoped(this IServiceCollection collection)
+ public static void TryAddScoped(this IServiceCollection collection)
where TService : class
where TImplementation : class, TService
{
@@ -406,7 +407,7 @@ public static void TryAddScoped(
/// The type of the service to register.
public static void TryAddSingleton(
this IServiceCollection collection,
- Type service)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
{
if (collection == null)
{
@@ -433,7 +434,7 @@ public static void TryAddSingleton(
public static void TryAddSingleton(
this IServiceCollection collection,
Type service,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (collection == null)
{
@@ -492,7 +493,7 @@ public static void TryAddSingleton(
///
/// The type of the service to add.
/// The .
- public static void TryAddSingleton(this IServiceCollection collection)
+ public static void TryAddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection)
where TService : class
{
if (collection == null)
@@ -511,7 +512,7 @@ public static void TryAddSingleton(this IServiceCollection collection)
/// The type of the service to add.
/// The type of the implementation to use.
/// The .
- public static void TryAddSingleton(this IServiceCollection collection)
+ public static void TryAddSingleton(this IServiceCollection collection)
where TService : class
where TImplementation : class, TService
{
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj
index a8e1db4822e590..d1955eaf4e8998 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj
@@ -16,6 +16,9 @@
Link="Common\src\Extensions\ActivatorUtilities\ActivatorUtilitiesConstructorAttribute.cs" />
+
+
+
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs
index 23cf01a1272d39..1de2b83d156f0c 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceCollectionServiceExtensions.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Extensions.DependencyInjection
{
@@ -23,7 +24,7 @@ public static class ServiceCollectionServiceExtensions
public static IServiceCollection AddTransient(
this IServiceCollection services,
Type serviceType,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (services == null)
{
@@ -86,7 +87,7 @@ public static IServiceCollection AddTransient(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddTransient(this IServiceCollection services)
+ public static IServiceCollection AddTransient(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
@@ -108,7 +109,7 @@ public static IServiceCollection AddTransient(this IS
///
public static IServiceCollection AddTransient(
this IServiceCollection services,
- Type serviceType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
{
if (services == null)
{
@@ -131,7 +132,7 @@ public static IServiceCollection AddTransient(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddTransient(this IServiceCollection services)
+ public static IServiceCollection AddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services)
where TService : class
{
if (services == null)
@@ -201,8 +202,6 @@ public static IServiceCollection AddTransient(
return services.AddTransient(typeof(TService), implementationFactory);
}
-
-
///
/// Adds a scoped service of the type specified in with an
/// implementation of the type specified in to the
@@ -216,7 +215,7 @@ public static IServiceCollection AddTransient(
public static IServiceCollection AddScoped(
this IServiceCollection services,
Type serviceType,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (services == null)
{
@@ -279,7 +278,7 @@ public static IServiceCollection AddScoped(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddScoped(this IServiceCollection services)
+ public static IServiceCollection AddScoped(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
@@ -301,7 +300,7 @@ public static IServiceCollection AddScoped(this IServ
///
public static IServiceCollection AddScoped(
this IServiceCollection services,
- Type serviceType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
{
if (services == null)
{
@@ -324,7 +323,7 @@ public static IServiceCollection AddScoped(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddScoped(this IServiceCollection services)
+ public static IServiceCollection AddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services)
where TService : class
{
if (services == null)
@@ -408,7 +407,7 @@ public static IServiceCollection AddScoped(
public static IServiceCollection AddSingleton(
this IServiceCollection services,
Type serviceType,
- Type implementationType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (services == null)
{
@@ -471,7 +470,7 @@ public static IServiceCollection AddSingleton(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddSingleton(this IServiceCollection services)
+ public static IServiceCollection AddSingleton(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
@@ -493,7 +492,7 @@ public static IServiceCollection AddSingleton(this IS
///
public static IServiceCollection AddSingleton(
this IServiceCollection services,
- Type serviceType)
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
{
if (services == null)
{
@@ -516,7 +515,7 @@ public static IServiceCollection AddSingleton(
/// The to add the service to.
/// A reference to this instance after the operation has completed.
///
- public static IServiceCollection AddSingleton(this IServiceCollection services)
+ public static IServiceCollection AddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services)
where TService : class
{
if (services == null)
@@ -651,7 +650,7 @@ public static IServiceCollection AddSingleton(
private static IServiceCollection Add(
IServiceCollection collection,
Type serviceType,
- Type implementationType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,
ServiceLifetime lifetime)
{
var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs
index d5fed233c6b59c..57a6d8d33f7d7d 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceDescriptor.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Extensions.DependencyInjection
{
@@ -20,7 +21,7 @@ public class ServiceDescriptor
/// The of the service.
public ServiceDescriptor(
Type serviceType,
- Type implementationType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,
ServiceLifetime lifetime)
: this(serviceType, lifetime)
{
@@ -96,6 +97,7 @@ private ServiceDescriptor(Type serviceType, ServiceLifetime lifetime)
public Type ServiceType { get; }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
public Type? ImplementationType { get; }
public object? ImplementationInstance { get; }
@@ -151,7 +153,7 @@ internal Type GetImplementationType()
/// The type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Transient()
+ public static ServiceDescriptor Transient()
where TService : class
where TImplementation : class, TService
{
@@ -166,7 +168,9 @@ public static ServiceDescriptor Transient()
/// The type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Transient(Type service, Type implementationType)
+ public static ServiceDescriptor Transient(
+ Type service,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (service == null)
{
@@ -254,7 +258,7 @@ public static ServiceDescriptor Transient(Type service, FuncThe type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Scoped()
+ public static ServiceDescriptor Scoped()
where TService : class
where TImplementation : class, TService
{
@@ -269,7 +273,9 @@ public static ServiceDescriptor Scoped()
/// The type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Scoped(Type service, Type implementationType)
+ public static ServiceDescriptor Scoped(
+ Type service,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
return Describe(service, implementationType, ServiceLifetime.Scoped);
}
@@ -347,7 +353,7 @@ public static ServiceDescriptor Scoped(Type service, FuncThe type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Singleton()
+ public static ServiceDescriptor Singleton()
where TService : class
where TImplementation : class, TService
{
@@ -362,7 +368,9 @@ public static ServiceDescriptor Singleton()
/// The type of the service.
/// The type of the implementation.
/// A new instance of .
- public static ServiceDescriptor Singleton(Type service, Type implementationType)
+ public static ServiceDescriptor Singleton(
+ Type service,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
if (service == null)
{
@@ -488,7 +496,7 @@ public static ServiceDescriptor Singleton(
return new ServiceDescriptor(serviceType, implementationInstance);
}
- private static ServiceDescriptor Describe(ServiceLifetime lifetime)
+ private static ServiceDescriptor Describe(ServiceLifetime lifetime)
where TService : class
where TImplementation : class, TService
{
@@ -507,7 +515,10 @@ private static ServiceDescriptor Describe(ServiceLife
/// The type of the implementation.
/// The lifetime of the service.
/// A new instance of .
- public static ServiceDescriptor Describe(Type serviceType, Type implementationType, ServiceLifetime lifetime)
+ public static ServiceDescriptor Describe(
+ Type serviceType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,
+ ServiceLifetime lifetime)
{
return new ServiceDescriptor(serviceType, implementationType, lifetime);
}
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj
index 17dc779a71056e..de407f2933ae4f 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj
@@ -25,6 +25,12 @@
Link="Common\src\Extensions\TypeNameHelper\TypeNameHelper.cs" />
+
+
+
+
+
+
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs
index 2bf5ee16fc8e15..4aec44848ae0e1 100644
--- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs
@@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Internal;
@@ -244,16 +245,16 @@ private ServiceCallSite TryCreateOpenGeneric(ServiceDescriptor descriptor, Type
return null;
}
- private ServiceCallSite CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType,
+ private ServiceCallSite CreateConstructorCallSite(
+ ResultCache lifetime,
+ Type serviceType,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,
CallSiteChain callSiteChain)
{
try
{
callSiteChain.Add(serviceType, implementationType);
- ConstructorInfo[] constructors = implementationType.GetTypeInfo()
- .DeclaredConstructors
- .Where(constructor => constructor.IsPublic)
- .ToArray();
+ ConstructorInfo[] constructors = implementationType.GetConstructors();
ServiceCallSite[] parameterCallSites = null;
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs
new file mode 100644
index 00000000000000..eef18d380d1e25
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
+class Program
+{
+ static int Main(string[] args)
+ {
+ ServiceProvider provider = new ServiceCollection().BuildServiceProvider();
+
+ // ActivatorUtilities.CreateFactory fails due to https://github.com/mono/linker/issues/1398
+ //ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty());
+ //ServiceA serviceA = factory(provider, null) as ServiceA;
+ ServiceB serviceB = ActivatorUtilities.CreateInstance(provider, typeof(ServiceB)) as ServiceB;
+ ServiceC serviceC = ActivatorUtilities.CreateInstance(provider);
+ ServiceD serviceD = ActivatorUtilities.GetServiceOrCreateInstance(provider, typeof(ServiceD)) as ServiceD;
+ ServiceE serviceE = ActivatorUtilities.GetServiceOrCreateInstance(provider);
+
+ if (//serviceA is null ||
+ serviceB is null ||
+ serviceC is null ||
+ serviceD is null ||
+ serviceE is null)
+ {
+ return -1;
+ }
+
+ return 100;
+ }
+
+ private class ServiceA { }
+ private class ServiceB { }
+ private class ServiceC { }
+ private class ServiceD { }
+ private class ServiceE { }
+}
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj
new file mode 100644
index 00000000000000..e1f5ef6af8cd5b
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/Microsoft.Extensions.DependencyInjection.TrimmingTests.proj
@@ -0,0 +1,14 @@
+
+
+
+
+ Microsoft.Extensions.DependencyInjection
+
+
+
+
+
+
+
+
+
diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs
new file mode 100644
index 00000000000000..58a1c8b10ab40c
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ServiceCollectionExtensionsTests.cs
@@ -0,0 +1,83 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.DependencyInjection;
+
+class Program
+{
+ static int Main(string[] args)
+ {
+ IServiceCollection descriptors = new ServiceCollection();
+ descriptors.AddTransient();
+ descriptors.AddScoped(typeof(ServiceB));
+ descriptors.AddSingleton(typeof(IServiceC), typeof(ServiceC));
+
+ descriptors.AddTransient();
+ descriptors.AddTransient();
+ descriptors.AddTransient(typeof(IServiceF), typeof(ServiceF));
+
+ descriptors.AddTransient();
+ descriptors.AddTransient(typeof(Logger<>));
+
+ descriptors.AddTransient();
+ descriptors.AddTransient();
+
+ ServiceProvider provider = descriptors.BuildServiceProvider();
+
+ if (provider.GetService() is null ||
+ provider.GetService() is null ||
+ provider.GetService() is null ||
+ provider.GetService()?.ServiceE?.ServiceD is null ||
+ provider.GetService>() is null)
+ {
+ return -1;
+ }
+
+ int hServices = 0;
+ foreach (IServiceH h in provider.GetServices())
+ {
+ hServices++;
+ if (h == null)
+ {
+ return -1;
+ }
+ }
+
+ if (hServices != 2)
+ {
+ return -1;
+ }
+
+ return 100;
+ }
+
+ private class ServiceA { }
+ private class ServiceB { }
+ private interface IServiceC { }
+ private class ServiceC : IServiceC { }
+
+ public interface IServiceD { }
+ public interface IServiceE { IServiceD ServiceD { get; } }
+ public interface IServiceF { IServiceE ServiceE { get; } }
+ public class ServiceD : IServiceD
+ {
+ }
+ public class ServiceE : IServiceE
+ {
+ public IServiceD ServiceD { get; }
+ public ServiceE(IServiceD d) { ServiceD = d; }
+ }
+ public class ServiceF : IServiceF
+ {
+ public IServiceE ServiceE { get; }
+ public ServiceF(IServiceE e) { ServiceE = e; }
+ }
+
+ public class Logger { }
+ public interface IServiceG { }
+ public class ServiceG : IServiceG { }
+
+ public interface IServiceH { }
+ public class ServiceH1 : IServiceH { }
+ public class ServiceH2 : IServiceH { }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs
index eefc9c442925bb..2d82ed0c0e7f50 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs
@@ -13,7 +13,12 @@ namespace System.Diagnostics.CodeAnalysis
/// . So it is always preserved in the compiled assembly.
///
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
- public sealed class UnconditionalSuppressMessageAttribute : Attribute
+#if SYSTEM_PRIVATE_CORELIB
+ public
+#else
+ internal
+#endif
+ sealed class UnconditionalSuppressMessageAttribute : Attribute
{
///
/// Initializes a new instance of the