csharp-assembly-inspection
Skill2 starsChanged 42 days agoMITView on GitHub
Use when a C#/.NET question is about the built artifact rather than the source, such as manifest resources, assembly references, what types or members actually shipped, whether a NuGet package still carries PRI/resource payloads, or whether the compiled surface matches the code. Prefer a throwaway single-file `dotnet run inspect.cs` tool using `System.Reflection.Metadata` and `PEReader` for read-only ECMA inspection; use `System.Reflection` only when runtime-visible type/member details are required.
In this repository56 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- benchmarkingSkill
- commit-messagesSkill
- csharp-15-syntaxSkill
- csharp-aot-trimmingSkill
- csharp-api-designSkill
- csharp-asyncSkill
- csharp-collections-modernSkill
- csharp-concurrency-primitivesSkill
- csharp-data-layoutSkill
- csharp-debuggingSkill
- csharp-discardsSkill
- csharp-disposable-patternsSkill
- csharp-docsSkill
- csharp-error-handlingSkill
- csharp-extension-membersSkill
- csharp-generics-modernSkill
- csharp-guard-clausesSkill
- csharp-json-source-generationSkill
- csharp-language-versionsSkill
- csharp-logging-diagnosticsSkill
- csharp-lspSkill
- csharp-modern-typesSkill
- csharp-nullabilitySkill
- csharp-nullable-migrationSkill
- csharp-nunitSkill
- csharp-pattern-matchingSkill
- csharp-performanceSkill
- csharp-polyfillsSkill
- csharp-source-generatorsSkill
- csharp-static-lambdasSkill
- csharp-string-handlingSkill
- csharp-tunitSkill
- csharp-verificationSkill
- dispatching-subagentsSkill
- dotnet-11-librariesSkill
- dotnet-analyzersSkill
- dotnet-central-package-managementSkill
- dotnet-file-based-appsSkill
- dotnet-msbuild-usingsSkill
- dotnet-multi-targetingSkill
- dotnet-project-hygieneSkill
- dotnet-runSkill
- dotnet-runtime-asyncSkill
- dotnet-slnxSkill
- dotnet-test-platformsSkill
- executing-plansSkill
- performance-bounded-deduplicationSkill
- roslyn-analyzer-performanceSkill
- roslyn-discoverySkill
- roslyn-duplicate-detectionSkill
- roslyn-guard-rewritersSkill
- roslyn-rewritersSkill
- subagent-driven-developmentSkill
- tddSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 14
System.Reflection: only when you need the runtime surface: did type X survive, is it abstract, which methods are virtual, which … - Distinctive: line 16
Start with metadata. Escalate to reflection only if metadata is not enough.
- Distinctive: line 20
Use a throwaway single-file program when the question is about managed contents:
- Distinctive: line 67
When the question is about the runtime-visible shape of a type, load the assembly deliberately:
- Distinctive: line 88
Use this for API-surface confirmation after a package upgrade or shim migration.
- Distinctive: line 93
Run a metadata query over the DLL to separate "managed manifest resource" from "loose file in the package/output".
- Distinctive: line 94
If needed, load the assembly and inspect the exact type/member surface.
- Distinctive: line 95
Only after that, go back to source-level Roslyn to explain where the artifact came from.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Compiled artifact inspection (.NET)
Roslyn answers questions about source. It does not answer questions about the binary that was actually produced. When the problem is "what shipped?", "what resources are really in this DLL?", "does this package still carry a .pri file?", or "what public members does the compiled type expose?", switch layers and inspect the artifact directly.
Use the right layer
- File/package layout first for loose payload questions:
unzip -l package.nupkg,find obj -name '*.pri',find bin -name '*.resources'. System.Reflection.Metadata+PEReaderfor read-only ECMA metadata: assembly name, references, manifest resources, type definitions, exported types. This is the default because it does not load the assembly.System.Reflectiononly when you need the runtime surface: did typeXsurvive, is it abstract, which methods are virtual, which properties are public.
Start with metadata. Escalate to reflection only if metadata is not enough.
Metadata-first example
Use a throwaway single-file program when the question is about managed contents:
using System;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
foreach (var path in args)
{
Console.WriteLine($"ASSEMBLY {path}");
using var stream = File.OpenRead(path);
using var pe = new PEReader(stream);
if (!pe.HasMetadata)
{
Console.WriteLine(" no metadata");
continue;
}
var reader = pe.GetMetadataReader();
var assembly = reader.GetAssemblyDefinition();
Console.WriteLine($" name: {reader.GetString(assembly.Name)}");
Console.WriteLine($" manifest resources: {reader.ManifestResources.Count}");
foreach (var handle in reader.ManifestResources)
{
var resource = reader.GetManifestResource(handle);
Console.WriteLine(
$" {reader.GetString(resource.Name)} | attrs={resource.Attributes} | impl={resource.Implementation.Kind} | offset={resource.Offset}");
}
Console.WriteLine($" assembly references: {reader.AssemblyReferences.Count}");
foreach (var handle in reader.AssemblyReferences)
{
var reference = reader.GetAssemblyReference(handle);
Console.WriteLine($" {reader.GetString(reference.Name)}");
}
}This settles questions like:
- Does the managed DLL embed any manifest resources at all?
- Which assemblies does it reference after the actual build?
- Did the package change the managed dependency graph?
Reflection example
When the question is about the runtime-visible shape of a type, load the assembly deliberately:
using System;
using System.Reflection;
var asm = Assembly.LoadFrom(Environment.GetEnvironmentVariable("RXDLL"));
var t = asm.GetType("System.Reactive.Concurrency.LocalScheduler");
Console.WriteLine($"Type: {t} (abstract={t?.IsAbstract})");
foreach (var m in t!.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
var kind = m.IsAbstract ? "abstract" : m.IsVirtual ? "virtual" : "";
Console.WriteLine(
$" {kind} {m.ReturnType.Name} {m.Name}{(m.IsGenericMethodDefinition ? "<T>" : "")}({string.Join(", ", Array.ConvertAll(m.GetParameters(), p => p.ParameterType.Name))})");
}
foreach (var p in t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
Console.WriteLine($" prop {p.PropertyType.Name} {p.Name}");Use this for API-surface confirmation after a package upgrade or shim migration.
Practical workflow
- Inspect the package/output layout if the issue mentions
.pri,.resources, native assets, or build payloads. - Run a metadata query over the DLL to separate "managed manifest resource" from "loose file in the package/output".
- If needed, load the assembly and inspect the exact type/member surface.
- Only after that, go back to source-level Roslyn to explain where the artifact came from.
Important distinctions
ManifestResources.Count == 0means no managed embedded manifest resources in that assembly. It does not prove the package/output contains no loose.pri,.resources, or native files.- A NuGet package can ship extra files next to the DLL even when the DLL metadata is empty. Inspect both the package archive and the assembly.
- Reflection can fail if dependencies are missing and can trigger type-loading behavior. If metadata answers the question, stop there.
- For source questions like "who implements this interface?" or "which files use this symbol?", use
roslyn-discoveryinstead.
Anti-patterns
- Guessing from source that a resource or reference must still exist in the built DLL.
- Using reflection first for a question metadata could answer safely.
- Treating a package payload problem as if it must be a managed manifest-resource problem.
- Declaring a build pipeline issue solved without inspecting the generated artifact.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

