Instructions for AI agents working on this codebase.
Tokenizer is a C# library that extracts structured information from blocks of text using pattern matching and reflects them onto .NET objects. Published as a NuGet package.
- Targets: .NET Standard 2.0, .NET 8.0, and .NET 10.0
- Root namespace:
Tokens(notTokenizer) - Language: C# with
LangVersion=latest, nullable reference types enabled
# Build
dotnet build ./src/Tokenizer/Tokenizer.csproj -c Release
# Run all tests
dotnet test ./tests/Tokenizer.Tests/Tokenizer.Tests.csproj
# Run a single test by full name
dotnet test ./tests/Tokenizer.Tests/Tokenizer.Tests.csproj --filter "FullyQualifiedName~ClassName.MethodName"
# Run tests matching a pattern
dotnet test ./tests/Tokenizer.Tests/Tokenizer.Tests.csproj --filter "ClassName"See ARCHITECTURE.md for the compilation pipeline, tokenization engine, extension points, and async path.
new Tokenizer()-- default optionsnew Tokenizer(TokenizerOptions)-- custom optionsnew Tokenizer(TokenizerOptions, ILoggerFactory)-- with loggingnew TemplateMatcher(ITokenizer)-- multi-template matchingservices.AddTokenizer()-- DI registration
- Braces: Allman style
- Naming: Transformers as
[Action]Transformer, Validators as[Action]Validator, Exceptions as[Action]Exception - Private fields:
_camelCase(underscore prefix) - Constants and static readonly:
PascalCase - Interfaces:
IPascalCase - Conditional compilation: Required when using .NET 8.0+ features (Span, pattern matching) -- must provide .NET Standard 2.0 fallback
- No regions: Never use
#regionin source or tests - Async: Core logic is synchronous. Async overloads exist for stream/reader-based I/O.
- Logging: Uses
Microsoft.Extensions.Logging
Style and quality rules are enforced via .editorconfig and Roslyn analyzers. TreatWarningsAsErrors + EnforceCodeStyleInBuild means violations break the build locally and in CI.
Analyzer packages:
- Built-in .NET SDK analyzers (
AnalysisLevel=latest-None-- only explicitly enabled rules fire) Meziantou.Analyzer(shared viaDirectory.Build.props, all rules silent by default)
Enforced rules:
IDE0004-- Remove unnecessary castIDE0005-- No unused usingsIDE0040-- Explicit accessibility modifiers requiredIDE0044-- Make field readonlyIDE0055-- FormattingIDE0059-- Remove unnecessary value assignmentIDE0060-- No unused parametersIDE0161-- File-scoped namespace declarationsIDE1006-- Naming conventions enforcedCA1031-- Do not catch general exception typesCA1507-- Usenameofover string literalsCA1508-- Avoid dead conditional codeCA1825-- UseArray.Empty<T>()over zero-length allocationsCA2000-- Dispose objects before losing scopeCA2016-- Forward CancellationTokenCA2200-- Rethrow to preserve stack tracesCA2213-- Disposable fields should be disposed
Per-rule commands (useful for targeted fixes):
# Check one rule (dry run)
dotnet format style ./Tokenizer.sln --verify-no-changes --diagnostics IDE0005
# Auto-fix one rule
dotnet format style ./Tokenizer.sln --diagnostics IDE0005
# See violations for one rule from build output
dotnet build ./Tokenizer.sln 2>&1 | grep "CA1507"Source of truth: .editorconfig -- all rules and severities are defined there.
- Framework: xUnit 2.9.3 with NSubstitute for mocks
- Naming: Gherkin style --
GivenScenario_WhenAction_ThenResult() - Structure: Arrange / Act / Assert comments within tests
- Builders: Fluent test data builders in
tests/Tokenizer.Tests/Builders/(e.g.,TokenBuilder,TemplateBuilder) - Helpers: Use
Expect[Object][State]pattern for mock setup methods, placed at end of test class - Logging in tests: Serilog with
Serilog.Sinks.XUnitfor test output - File naming: Test file matches production class:
{ClassName}Tests.cs. If a single test fixture is too crowded, split into{ClassName}.{Scenario}.Tests.cs