CodeGuard.Cli
1.0.8
dotnet tool install --global CodeGuard.Cli --version 1.0.8
dotnet new tool-manifest
dotnet tool install --local CodeGuard.Cli --version 1.0.8
#tool dotnet:?package=CodeGuard.Cli&version=1.0.8
nuke :add-package CodeGuard.Cli --version 1.0.8
CodeGuard - DI Lifecycle Auditor
A .NET console tool that uses Roslyn API to analyze C# codebases for Dependency Injection (DI) service lifecycle optimization.
Features
- Service Registration Discovery - Detects
AddTransient,AddScoped,AddSingleton, and common extension methods - Dependency Graph Construction - Builds a graph of service dependencies from constructor analysis
- Captive Dependency Detection - Identifies lifetime mismatches (e.g., Singleton → Transient)
- Scope Leak Detection - Finds Singletons that depend on scoped services like DbContext
- Lifecycle Promotion Recommendations - Suggests safe promotions (Transient → Scoped → Singleton)
- Statelessness Analysis - Analyzes classes to determine if they're safe for longer lifetimes
- Multiple Output Formats - Console, JSON, SARIF, and HTML report formats
- File Export - Save reports to files for sharing or CI integration
- Optional Code Rewriting - Auto-apply lifecycle changes to your codebase
Installation
dotnet tool install --global CodeGuard.Cli
Usage
# Analyze a solution
dotnet codeguard path/to/your/Solution.sln
# Analyze a .slnx solution (XML format)
dotnet codeguard path/to/your/Solution.slnx
# Analyze a single project
dotnet codeguard path/to/your/Project.csproj
# Output as JSON
dotnet codeguard path/to/Solution.sln --format json
# Output as SARIF (for IDE integration)
dotnet codeguard path/to/Solution.sln --format sarif
# Output as HTML (for browser viewing)
dotnet codeguard path/to/Solution.sln --format html
# Export report to file
dotnet codeguard path/to/Solution.sln --format json --output report.json
dotnet codeguard path/to/Solution.sln --format html --output report.html
dotnet codeguard path/to/Solution.sln --format sarif -o results.sarif
# Verbose output
dotnet codeguard path/to/Solution.sln --verbose
# Auto-apply recommended changes
dotnet codeguard path/to/Solution.sln --rewrite
# Export unresolved dependencies to .codeguard.json
dotnet codeguard path/to/Solution.sln --export-unknowns
# Use a specific external registrations config file
dotnet codeguard path/to/Solution.sln --externals path/to/.codeguard.json
External Registrations
When your code depends on services registered by external libraries (NuGet packages, shared projects without source), CodeGuard can't see those registrations. The external registrations feature lets you define them manually so they participate in captive dependency analysis.
Workflow
1. Discover unknown dependencies:
dotnet codeguard MyApp.sln --export-unknowns
This creates or updates a .codeguard.json file next to your solution with entries like:
{
"version": 1,
"externalRegistrations": [
{
"serviceType": "MyCompany.Shared.IEmailService",
"lifetime": null,
"comment": "Used by MyApp.Services.NotificationService (parameter: emailService)"
},
{
"serviceType": "ThirdParty.Caching.ICacheProvider",
"lifetime": null,
"comment": "Used by MyApp.Services.ProductService (parameter: cache)"
}
]
}
2. Define the lifetimes:
Edit the file and fill in the lifetime values based on how the libraries register these services:
{
"version": 1,
"externalRegistrations": [
{
"serviceType": "MyCompany.Shared.IEmailService",
"lifetime": "Scoped",
"comment": "Registered as Scoped in SharedLib.AddEmailServices()"
},
{
"serviceType": "ThirdParty.Caching.ICacheProvider",
"lifetime": "Singleton",
"comment": "Registered as Singleton in ThirdParty.AddCaching()"
}
]
}
Valid lifetime values: Transient, Scoped, Singleton.
3. Run analysis again:
dotnet codeguard MyApp.sln
Now CodeGuard includes those external services in captive dependency detection. For example, if a Singleton depends on IEmailService (Scoped), it will be flagged as a violation.
Notes
- The config file is automatically discovered in the same directory as the solution/project file
- Use
--externals <path>to specify a custom location - Running
--export-unknownsagain merges new entries without overwriting your existing definitions - Entries with
"lifetime": nullare still unresolved and won't participate in analysis - Well-known framework types (
ILogger,IOptions<T>,IConfiguration, etc.) are never exported as unknowns
CLI Options
| Option | Description |
|---|---|
--format <format> |
Output format: console (default), json, sarif, html |
--output <file>, -o |
Write report to file instead of stdout |
--verbose |
Enable verbose output with detailed progress |
--rewrite |
Automatically rewrite registration code with recommendations |
--externals <file> |
Path to external registrations config (.codeguard.json) |
--export-unknowns |
Export unresolved dependencies to the config file for review |
--help, -h |
Show help message |
Supported Registration Patterns
CodeGuard detects the following DI registration methods:
Core Methods:
AddTransient,AddScoped,AddSingletonTryAddTransient,TryAddScoped,TryAddSingleton
Common Extensions (Scoped by default):
AddDbContext,AddDbContextPool,AddDbContextFactoryAddIdentity,AddIdentityCore,AddDefaultIdentity
Common Extensions (Singleton by default):
AddHttpClient,AddMemoryCache,AddDistributedMemoryCacheAddLogging,AddOptions,ConfigureAddHostedService,AddMediatR,AddAutoMapperAddSignalR,AddGrpc
Common Extensions (Transient by default):
AddHttpContextAccessorAddControllers,AddControllersWithViews,AddRazorPages,AddMvc
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success - no issues found |
| 1 | Warnings - potential issues detected |
| 2 | Errors - captive dependencies or scope leaks found |
Example Output
CodeGuard DI Lifecycle Auditor v1.0.0
=====================================
Analyzing: MyApp.sln
Loaded 3 projects, 42 source files
Errors:
[ERROR] Singleton 'CacheService' depends on Transient 'DataProcessor'
Chain: CacheService → DataProcessor
Recommendations:
[Transient] → [Singleton] : UserValidator
- Class is stateless (no mutable fields)
- No scope-infected dependencies
[Transient] → [Scoped] : OrderService
- Class is stateless
- Depends on DbContext (scope-infected)
Summary: 1 error, 0 warnings, 2 promotion recommendations
Requirements
- .NET 8.0 or later
- MSBuild (included with .NET SDK)
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
Initial release of CodeGuard DI Lifecycle Auditor