From 0d122b12ec1266d376817728f538837f513b8674 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 17 Nov 2020 20:33:27 -0800 Subject: [PATCH] Fix NRE when default value is null and ServiceCallSite is not found (#44675) * Fix NRE when default value is null and ServiceCallSite is not found --- .../src/ServiceLookup/ConstantCallSite.cs | 6 +++-- .../tests/DI.Tests/CallSiteTests.cs | 31 ++++++++++++++++++++++ .../DI.Tests/ServiceProviderCompilationTest.cs | 1 + 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs index acc1d96..bd09485 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ConstantCallSite.cs @@ -7,10 +7,12 @@ namespace Microsoft.Extensions.DependencyInjection.ServiceLookup { internal class ConstantCallSite : ServiceCallSite { + private readonly Type _serviceType; internal object DefaultValue { get; } public ConstantCallSite(Type serviceType, object defaultValue): base(ResultCache.None) { + _serviceType = serviceType ?? throw new ArgumentNullException(nameof(serviceType)); if (defaultValue != null && !serviceType.IsInstanceOfType(defaultValue)) { throw new ArgumentException(SR.Format(SR.ConstantCantBeConvertedToServiceType, defaultValue.GetType(), serviceType)); @@ -19,8 +21,8 @@ namespace Microsoft.Extensions.DependencyInjection.ServiceLookup DefaultValue = defaultValue; } - public override Type ServiceType => DefaultValue.GetType(); - public override Type ImplementationType => DefaultValue.GetType(); + public override Type ServiceType => DefaultValue?.GetType() ?? _serviceType; + public override Type ImplementationType => DefaultValue?.GetType() ?? _serviceType; public override CallSiteKind Kind { get; } = CallSiteKind.Constant; } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/CallSiteTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/CallSiteTests.cs index 3dc3cec..c83e277 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/CallSiteTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/CallSiteTests.cs @@ -264,6 +264,37 @@ namespace Microsoft.Extensions.DependencyInjection.Tests Assert.NotNull(compileCallSite); } + [Theory] + [InlineData(ServiceProviderMode.Default)] + [InlineData(ServiceProviderMode.Dynamic)] + [InlineData(ServiceProviderMode.Runtime)] + [InlineData(ServiceProviderMode.Expressions)] + [InlineData(ServiceProviderMode.ILEmit)] + private void NoServiceCallsite_DefaultValueNull_DoesNotThrow(ServiceProviderMode mode) + { + var descriptors = new ServiceCollection(); + descriptors.AddTransient(); + + var provider = descriptors.BuildServiceProvider(mode); + ServiceF instance = ActivatorUtilities.CreateInstance(provider); + + Assert.NotNull(instance); + } + + private interface IServiceG + { + } + + private class ServiceG + { + public ServiceG(IServiceG service = null) { } + } + + private class ServiceF + { + public ServiceF(ServiceG service) { } + } + private class ServiceD { public ServiceD(IEnumerable services) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderCompilationTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderCompilationTest.cs index 5c6853e..8094dde 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderCompilationTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceProviderCompilationTest.cs @@ -12,6 +12,7 @@ namespace Microsoft.Extensions.DependencyInjection.Tests public class ServiceProviderCompilationTest { [Theory] + [InlineData(ServiceProviderMode.Default, typeof(I999))] [InlineData(ServiceProviderMode.Dynamic, typeof(I999))] [InlineData(ServiceProviderMode.Runtime, typeof(I999))] [InlineData(ServiceProviderMode.ILEmit, typeof(I999))] -- 2.7.4