.claude/skills/embedded-resource-configuration/SKILL.md
Use when building a .NET library distributed via NuGet that needs default configuration values shipped with the assembly, when you want zero-configuration defaults that just work without file deployment, or when consumers need to override library settings via standard appsettings.json patterns. Covers three-tier configuration precedence: embedded JSON defaults compiled into the assembly via EmbeddedResource, consumer appsettings.json overrides, and hardcoded fallback values, plus the EmbeddedConfigLoader and LogicalName conventions. Domain: .NET Library Design, Configuration. Level: Intermediate. Tags: configuration, embedded-resource, nuget, library-defaults, appsettings.
npx skillsauth add klod68/littlerae embedded-resource-configurationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A .NET class library distributed via NuGet needs default configuration values that:
Traditional Content file deployment is fragile — NuGet content files may not copy correctly across TFMs, may collide with consumer files, or may be silently ignored.
Design a layered configuration system with three tiers (highest to lowest priority):
appsettings.json — consuming app overrides any value<EmbeddedResource>appsettings.jsonMyLibrary/
├── Settings/
│ └── library-defaults.json ← human-readable source, embedded at build time
{
"LibrarySettings": {
"DefaultLanguage": "en-US",
"LogFilePath": "MyLibrary-Log.txt",
"MaxRetryCount": 3,
"CacheTimeoutMinutes": 30
}
}
.csproj<ItemGroup>
<EmbeddedResource Include="Settings\library-defaults.json">
<LogicalName>MyLibrary.Settings.library-defaults.json</LogicalName>
</EmbeddedResource>
</ItemGroup>
Key distinction: Use
<EmbeddedResource>(compiled into assembly) — NOT<Content>(deployed alongside). SQL scripts, migration files, and other consumer-deployed assets should remain as<Content>.
Without
<LogicalName>: The resource name is auto-generated as{DefaultNamespace}.{FolderPath}.{FileName}with dots replacing path separators. Example: projectAcme.DataAccess, file atSettings/defaults.json→Acme.DataAccess.Settings.defaults.json. Use<LogicalName>to make the name explicit and refactor-safe.
The loader mechanism is separate from the settings accessor. Each has one reason to change.
internal static class EmbeddedConfigLoader
{
private const string ResourceName = "MyLibrary.Settings.library-defaults.json";
internal static IConfiguration Load()
{
var builder = new ConfigurationBuilder();
var stream = typeof(EmbeddedConfigLoader).Assembly
.GetManifestResourceStream(ResourceName);
if (stream is not null)
{
builder.AddJsonStream(stream);
}
return builder.Build();
}
}
internal static class LibrarySettings
{
private static readonly IConfiguration _libraryConfig = EmbeddedConfigLoader.Load();
public static string DefaultLanguage =>
ConsumerConfigHelper.GetValue("LibrarySettings:DefaultLanguage") // Tier 1
?? _libraryConfig["LibrarySettings:DefaultLanguage"] // Tier 2
?? "en-US"; // Tier 3
public static int MaxRetryCount =>
ConsumerConfigHelper.GetValue<int?>("LibrarySettings:MaxRetryCount") // Tier 1
?? _libraryConfig.GetValue<int?>("LibrarySettings:MaxRetryCount") // Tier 2
?? 3; // Tier 3
}
appsettings.json){
"LibrarySettings": {
"DefaultLanguage": "es-ES"
}
}
The consumer only overrides what they need. Everything else falls through to library defaults.
appsettings.json patternsappsettings.json directly)<Content> insteadconst or static readonlyAddJsonStream reads the stream during Build(). Don't try to reuse the stream.GetManifestResourceStream uses the logical name, not the file path.any/net9.0/), the any/any/ fallback is ignored. Keep embedded resources and content files on separate strategies.// Confirm the resource is embedded and named correctly
var names = typeof(EmbeddedConfigLoader).Assembly.GetManifestResourceNames();
Debug.Assert(names.Contains("MyLibrary.Settings.library-defaults.json"),
"Embedded resource not found — check <LogicalName> or auto-naming convention.");
tools
Use when cross-cutting concerns (logging, metrics, validation, authorization) are tangled into command handlers or service methods, when building database command pipelines with reorderable concerns, or when HTTP client pipelines or message handlers need composable, independently-replaceable processing stages. Covers ICommandInterceptor interface, InterceptorPipeline with reverse-chain construction, zero-cost Empty sentinel to skip overhead when no interceptors are registered, and ConfigureAwait(false) discipline for library code. Domain: Architecture, Cross-Cutting Concerns. Level: Intermediate. Tags: interceptor, pipeline, middleware, decorator, cross-cutting-concerns.
development
Use when writing integration tests for Razor Pages, MVC, or Minimal API applications to validate routing, middleware, page rendering, and HTTP behavior without a browser or live server, or when adding fast smoke tests to a CI pipeline. Covers WebApplicationFactory<Program> setup with public partial class Program, in-memory test server, AngleSharp HTML parsing, CSS selector assertions, redirect and status code testing, and a shared static fixture pattern for minimal per-test startup overhead. Domain: Testing, ASP.NET Core. Level: Intermediate. Tags: integration-testing, webapplicationfactory, razor-pages, anglesharp, http-testing.
development
Use when designing indexes for new tables, diagnosing slow queries that are not using indexes efficiently, reviewing index fragmentation and maintenance, or when the current indexing strategy results in key lookups, table scans, or missing index warnings. Covers clustered index key selection (narrow, unique, ever-increasing), non-clustered index design for query patterns, covering indexes with INCLUDE columns, filtered indexes for subset queries, composite index column ordering, DMV-based monitoring for missing and unused indexes, and rebuild vs reorganize maintenance thresholds. Domain: Database, Performance. Level: Intermediate. Tags: index, sql-server, covering-index, filtered-index, performance, dmv, maintenance.
development
Use when building a searchable in-memory catalog or registry for documentation sites, admin panels, or type/API browsers where you need keyword matching, fuzzy search, and ranked results without an external search engine or database. Covers RegistryService with weighted scoring across name, description, keywords, and method names; Levenshtein fuzzy matching; synonym expansion; category and subcategory filtering; and singleton DI registration for datasets of hundreds to low thousands of items. Domain: Search, Data Access Patterns. Level: Intermediate. Tags: search, registry, fuzzy-matching, in-memory, catalog, filtering.