-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ITelemetryModule singleton registration to support presence of keyed services #2908
base: main
Are you sure you want to change the base?
Conversation
…hen keyed services are registered.
/// <summary> | ||
/// When working with IServiceCossection, it can store three types of Implementations: | ||
/// ImplementationFactory, ImplementationInstance, and ImplementationType. | ||
/// We want to be able to add a Singleton but only if a user hasn't already done so. | ||
/// This class is to test all the various edge cases. | ||
/// </summary> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is as of 8.0.0 this summary is false.
There are new "keyed" forms of the possible registration types:
AddSingletonIfNotExists
could be made smarter to understand the new shape. But that would require an 8.0.0
bump for M.E.DI/.A in Microsoft.ApplicationInsights.AspNetCore
.
Easier IMO to just call into TryAddEnumerable
and let it sort out what to do!
Sorry about the whitespace on diff! Blame VS 🤣 |
@@ -37,6 +37,25 @@ namespace Microsoft.Extensions.DependencyInjection.Test | |||
|
|||
public class AddApplicationInsightsTelemetryTests : BaseTestClass | |||
{ | |||
[Fact] | |||
public static void TelemetryModuleResolvableWhenKeyedServiceRegistered() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test appears to pass even without your change.
I copied it locally and ran it in main branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. It looks like without the fix, worker service can't find any registered ITelemetryHttpModule
and the test fails. AspNetCore though finds RequestTrackingTelemetryModule
registered so the test passes.
With the fix in place there are actually 7 ITelemetryHttpModule
s registered. I updated the tests to validate all 7 are found when keyed service is added to the mix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just pushed updates to the test to improve them further. Added validation that a) DiagnosticsTelemetryModule
is present in the final list and b) if the user supplied one we don't end up with 2.
The bug report is for .NET 8, but does it apply for other .NET versions and .NET Framework? |
Could impact all runtimes. All user needs to do is take a dependency on something which a) brings in M.E.DI 8.0.0+ and b) registers a keyed service. In the case of the bug report, it is actually |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thanks for fixing this quicker. Could you please add a changelog entry.
@TimothyMothra @rajkumar-rangaraj I pushed a change to call I was looking through the history and trying to figure out why we had So my guess is we had |
@@ -332,7 +312,7 @@ private static void AddCommonInitializers(IServiceCollection services) | |||
private static void AddCommonTelemetryModules(IServiceCollection services) | |||
{ | |||
// Previously users were encouraged to manually add the DiagnosticsTelemetryModule. | |||
services.AddSingletonIfNotExists<ITelemetryModule, DiagnosticsTelemetryModule>(); | |||
services.TryAddEnumerable(ServiceDescriptor.Singleton<ITelemetryModule, DiagnosticsTelemetryModule>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TimothyMothra FYI I didn't make any other changes here but really all of the services.AddSingleton<ITelemetryModule, ...>();
calls should be TryAddEnumerable
calls. If user only calls registration once everything will be fine. But if they call one of the "Add" extensions more than once, they'll get duplicates of all of these modules. Typically "Add" extensions should be safe to be called more than once which is accomplished by calling TryAddSingleton
\ TryAddEnumerable
🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pinged @cijothomas offline to also take a look. He was involved in the previous PR #1886 |
Any updates on this? 👀👀 |
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" /> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.0" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks as though it introduces version-mismatch. It's worth considering either using 2.1.0 across the board or bump all to 8.0.
Fixes #2879
Relates to dotnet/extensions#5222
Changes
AddSingletonIfNotExists
custom implementation for detection of registered services and callTryAddEnumerable
instead because it understands keyed services added in 8.0.0