Recognise a native host as having no configuration system (#162) - #311
Merged
FreeAndNil merged 3 commits intoAug 20, 2026
Merged
Conversation
In a process that hosts the runtime natively there is no entry assembly for the configuration system to derive the config file path from, so reading an application setting fails in ClientConfigPaths with a PlatformNotSupportedException wrapped in a ConfigurationErrorsException. That matched none of the shapes IsMissingConfigurationSystem recognised, so log4net blamed the user's config file and repeated the report for every setting the static constructors read: seven log4net:ERROR blocks with a stack trace each, at startup, in a well configured application. A PlatformNotSupportedException anywhere in the inner exception chain is now treated as an absent configuration system, the same as the Native AOT case. A malformed config file cannot produce one, so unlike the FileNotFoundException and TypeLoadException cases it needs no check on which assembly it came from. The failure is logged once at debug level and application settings come from environment variables. Verified on Windows in a C++ host of the CoreCLR built for the purpose, in a host that loads the runtime through hostfxr, and in powershell.exe loading a netstandard2.0 build output: seven error blocks before, none after, and exactly one debug line with log4net.Internal.Debug on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The unit test for a natively hosted process builds the exception by hand, so it asserts what we believe the configuration system does rather than what it does. This adds a check that removes the entry assembly for real and reports what log4net writes while starting up, in the project that already exists to record what log4net can do in an unusual host. It cannot be one of the probes in the list: the configuration system caches its initialization and log4net reads its first application setting from a static constructor, so by the time any probe runs the outcome is already decided. The check therefore owns the process from its first statement and the runner selects it with an argument. Verified in both directions: it passes as committed, and reverting the PlatformNotSupportedException case makes it exit non-zero and print the seven error blocks it captured. JIT compiled only, deliberately. Native AOT trims the configuration system away, so the first setting read there fails as a missing constructor long before it can fail for want of an entry assembly: the published executable passes this check even with the fix reverted, which would be a green that cannot fail for the reason the check exists. The reason is recorded next to the CI step and on the class, so it does not get added back for symmetry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every test method, the fixture hooks and the layout factories now carry a summary saying what they assert, as does the converter that feeds arbitrary names to NamedPatternConverter. The factories note that DynamicPatternLayoutTest inherits this fixture and reruns the whole suite against a DynamicPatternLayout, which is not obvious from either file. The conditional using directive that came with it keeps System.Linq out of the net462 compilation, where nothing uses it, which clears an IDE0005 warning. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FreeAndNil
force-pushed
the
Feature/162-quiet-app-settings-in-a-native-host
branch
from
August 19, 2026 20:56
633d028 to
36aa1ed
Compare
fluffynuts
approved these changes
Aug 20, 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 #162
In a process that hosts the runtime natively there is no entry assembly for the
configuration system to derive the config file path from, so reading an
application setting fails in ClientConfigPaths with a PlatformNotSupportedException
wrapped in a ConfigurationErrorsException. That matched none of the shapes
IsMissingConfigurationSystem recognised, so log4net blamed the user's config file
and repeated the report for every setting the static constructors read: seven
log4net:ERROR blocks with a stack trace each, at startup, in a well configured
application.
A PlatformNotSupportedException anywhere in the inner exception chain is now
treated as an absent configuration system, the same as the Native AOT case. A
malformed config file cannot produce one, so unlike the FileNotFoundException and
TypeLoadException cases it needs no check on which assembly it came from. The
failure is logged once at debug level and application settings come from
environment variables.
Verified on Windows in a C++ host of the CoreCLR built for the purpose, in a host
that loads the runtime through hostfxr, and in powershell.exe loading a
netstandard2.0 build output: seven error blocks before, none after, and exactly one
debug line with log4net.Internal.Debug on.