Repository navigation
Let parameterized provider registrations take effect after AddEssentials() [patch] - #136
Merged
Merged
Conversation
…als() [patch] TryAddSingleton/TryAddEnumerable deduplicate on the concrete type, so once AddEssentials() had registered the defaults, AddXorObfuscationProvider(key) or AddNormalDistributionProvider(100, 15) silently did nothing: data was obfuscated with the public default key and distributions sampled the wrong parameters. The Xor, Caesar and BitRotate obfuscators and all ten distributions now register through Shared/ProviderRegistration.cs, which replaces an earlier registration of the same concrete type in place, so the order AddEssentials() chose for single-interface resolution is kept. AddEssentials() in turn keeps a registration the caller made before it, moving it to where the default would have gone, instead of overwriting it. Fixes #132 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011U7VEdh3f5sicnbD2XSo1a
|
matt-edmondson
deleted the
fix/132-parameterized-registration-replaces
branch
October 18, 2026 10:47
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #132
Problem
Every parameterized
Add…Provider(...)registered its instance withTryAddSingletonandTryAddEnumerable. Both of those deduplicate on the concrete type.AddEssentials()registers the defaults first, so a later call with arguments did nothing. For example,services.AddEssentials(); services.AddXorObfuscationProvider(key);kept obfuscating with the public default key. Likewise,AddNormalDistributionProvider(100, 15)still resolved N(0, 1).Change
Shared/ProviderRegistration.cs, linked likeDistributionArguments.cs.AddOrReplaceSingleton<TService, TImpl>replaces an earlier registration of the same concrete type, both the concrete-type descriptor and its member of the interface set. It replaces each one in place, so the orderAddEssentials()chose for single-interface resolution is kept. For example, Poisson stays the defaultIDiscreteDistributionafterAddPoissonDistributionProvider(7). Keyed descriptors are skipped.AddEssentials()must not overwrite a provider the caller registered before it. The bundled registrations of those ten providers therefore go throughAddDefaultOrKeep<T>. If the caller already registered the provider, its descriptor is moved to where the default would have gone, and no default is added. As a result,AddXorObfuscationProvider(key); AddEssentials();also resolves the keyed Xor as the defaultIObfuscationProvider, and both call orders behave the same.I chose replacing over throwing
InvalidOperationException, the issue's second option. With throwing,AddEssentials()followed by any configured call would fail, so the natural composition would still not work. Parameterless providers keep theirTryAddregistrations unchanged.Tests
New
ParameterizedRegistrationTests:Xor_Key_Registered_After_AddEssentials_Takes_EffectandXor_Key_Registered_Before_AddEssentials_Survives_Itcover both call orders. The interface and the concrete type each resolve the keyed output, and Xor is listed once.Normal_Parameters_Take_Effect_On_Either_Side_Of_AddEssentialscovers both orders for a distribution.Replacing_A_Registration_Keeps_Its_Place_And_Lists_It_Oncecovers Poisson, Caesar and BitRotate afterAddEssentials(). The defaults per category don't change, and nothing is duplicated.A_Second_Call_Replaces_A_Distribution_Outside_AddEssentialscovers Triangular called twice.With the fix reverted, all 5 tests fail. With the fix in place, the full
Essentials.Testssuite passes (1043 tests), anddotnet build -c Releasesucceeds with no warnings.Generated by Claude Code