diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/DependencyInjectionEventSource.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/DependencyInjectionEventSource.cs index 338325edb830f6..03b245224d8bb6 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/DependencyInjectionEventSource.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/DependencyInjectionEventSource.cs @@ -79,9 +79,9 @@ public void ServiceRealizationFailed(string? exceptionMessage, int serviceProvid [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] [Event(7, Level = EventLevel.Informational, Keywords = Keywords.ServiceProviderInitialized)] - private void ServiceProviderBuilt(int serviceProviderHashCode, int singletonServices, int scopedServices, int transientServices) + private void ServiceProviderBuilt(int serviceProviderHashCode, int singletonServices, int scopedServices, int transientServices, int closedGenericsServices, int openGenericsServices) { - WriteEvent(7, serviceProviderHashCode, singletonServices, scopedServices, transientServices); + WriteEvent(7, serviceProviderHashCode, singletonServices, scopedServices, transientServices, closedGenericsServices, openGenericsServices); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", @@ -174,6 +174,8 @@ private void WriteServiceProviderBuilt(ServiceProvider provider) int singletonServices = 0; int scopedServices = 0; int transientServices = 0; + int closedGenericsServices = 0; + int openGenericsServices = 0; StringBuilder descriptorBuilder = new StringBuilder("{ \"descriptors\":[ "); bool firstDescriptor = true; @@ -202,11 +204,23 @@ private void WriteServiceProviderBuilt(ServiceProvider provider) transientServices++; break; } + + if (descriptor.ServiceType.IsGenericType) + { + if (descriptor.ServiceType.IsConstructedGenericType) + { + closedGenericsServices++; + } + else + { + openGenericsServices++; + } + } } descriptorBuilder.Append(" ] }"); int providerHashCode = provider.GetHashCode(); - ServiceProviderBuilt(providerHashCode, singletonServices, scopedServices, transientServices); + ServiceProviderBuilt(providerHashCode, singletonServices, scopedServices, transientServices, closedGenericsServices, openGenericsServices); string descriptorString = descriptorBuilder.ToString(); int chunkCount = descriptorString.Length / MaxChunkSize + (descriptorString.Length % MaxChunkSize > 0 ? 1 : 0); diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/DependencyInjectionEventSourceTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/DependencyInjectionEventSourceTests.cs index 11d8ae91570ecc..deaaba56b47fd2 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/DependencyInjectionEventSourceTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/DependencyInjectionEventSourceTests.cs @@ -241,14 +241,18 @@ public void EmitsServiceProviderBuilt() serviceCollection.AddScoped(); serviceCollection.AddTransient(); serviceCollection.AddSingleton(); + serviceCollection.AddScoped(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>)); + serviceCollection.AddTransient, FakeOpenGenericService>(); using ServiceProvider provider = serviceCollection.BuildServiceProvider(); EventWrittenEventArgs serviceProviderBuiltEvent = _listener.EventData.Single(e => e.EventName == "ServiceProviderBuilt"); GetProperty(serviceProviderBuiltEvent, "serviceProviderHashCode"); // assert hashcode exists as an int Assert.Equal(4, GetProperty(serviceProviderBuiltEvent, "singletonServices")); - Assert.Equal(1, GetProperty(serviceProviderBuiltEvent, "scopedServices")); - Assert.Equal(2, GetProperty(serviceProviderBuiltEvent, "transientServices")); + Assert.Equal(2, GetProperty(serviceProviderBuiltEvent, "scopedServices")); + Assert.Equal(3, GetProperty(serviceProviderBuiltEvent, "transientServices")); + Assert.Equal(1, GetProperty(serviceProviderBuiltEvent, "closedGenericsServices")); + Assert.Equal(1, GetProperty(serviceProviderBuiltEvent, "openGenericsServices")); Assert.Equal(7, serviceProviderBuiltEvent.EventId); EventWrittenEventArgs serviceProviderDescriptorsEvent = _listener.EventData.Single(e => e.EventName == "ServiceProviderDescriptors"); @@ -290,6 +294,16 @@ public void EmitsServiceProviderBuilt() " \"serviceType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.IFakeService\",", " \"lifetime\": \"Singleton\",", " \"implementationType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.FakeDisposableCallbackInnerService\"", + " },", + " {", + " \"serviceType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.IFakeOpenGenericService`1[TValue]\",", + " \"lifetime\": \"Scoped\",", + " \"implementationType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.FakeOpenGenericService`1[TVal]\"", + " },", + " {", + " \"serviceType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.IFakeOpenGenericService`1[Microsoft.Extensions.DependencyInjection.Specification.Fakes.PocoClass]\",", + " \"lifetime\": \"Transient\",", + " \"implementationType\": \"Microsoft.Extensions.DependencyInjection.Specification.Fakes.FakeOpenGenericService`1[Microsoft.Extensions.DependencyInjection.Specification.Fakes.PocoClass]\"", " }", " ]", "}"),