CodeGuard.Cli 1.0.8

dotnet tool install --global CodeGuard.Cli --version 1.0.8
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local CodeGuard.Cli --version 1.0.8
                    
This package contains a .NET tool you can call from the shell/command line.
#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-unknowns again merges new entries without overwriting your existing definitions
  • Entries with "lifetime": null are 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, AddSingleton
  • TryAddTransient, TryAddScoped, TryAddSingleton

Common Extensions (Scoped by default):

  • AddDbContext, AddDbContextPool, AddDbContextFactory
  • AddIdentity, AddIdentityCore, AddDefaultIdentity

Common Extensions (Singleton by default):

  • AddHttpClient, AddMemoryCache, AddDistributedMemoryCache
  • AddLogging, AddOptions, Configure
  • AddHostedService, AddMediatR, AddAutoMapper
  • AddSignalR, AddGrpc

Common Extensions (Transient by default):

  • AddHttpContextAccessor
  • AddControllers, 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
1.0.8 114 7/28/2026
1.0.7 106 7/28/2026
1.0.1 153 3/26/2026
1.0.0 135 2/13/2026

Initial release of CodeGuard DI Lifecycle Auditor