Skip to content
Development
Skill

/detect-static-dependencies

ACTIVATION PREREQUISITE: the request or discovered target must explicitly identify C#, .NET, `.cs`, or `.csproj`; otherwise stay dormant without invoking this skill. USE FOR: locating System.DateTime.Now/UtcNow, System.IO.File/Directory, System.Environment, HttpClient, Console,

From plugin
dotnet-skills
5.4k100 skills16 agents
Install
$ npx -y skills add dotnet/skills --skill detect-static-dependencies --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/detect-static-dependencies

Context preview

The summary Claude sees to decide when to auto-load this skill.

ACTIVATION PREREQUISITE: the request or discovered target must explicitly identify C#, .NET, `.cs`, or `.csproj`; otherwise stay dormant without invoking this skill. USE FOR: locating System.DateTime.Now/UtcNow, System.IO.File/Directory, System.Environment, HttpClient, Console,

SKILL.md

detect-static-dependencies.SKILL.md
name: detect-static-dependencies
description: >
  ACTIVATION PREREQUISITE: the request or discovered target must explicitly
  identify C#, .NET, `.cs`, or `.csproj`; otherwise stay dormant without
  invoking this skill. USE FOR: locating
  System.DateTime.Now/UtcNow, System.IO.File/Directory, System.Environment,
  HttpClient, Console, or Process usage in C#; auditing C# code for hard-to-test
  framework dependencies; or verifying those C# calls are already abstracted.
  DO NOT USE FOR: any target lacking the activation prerequisite; generating
  wrappers (use generate-testability-wrappers); migrating code (use
  migrate-static-to-wrapper); or general code review.
license: MIT

Detect Static Dependencies

Scan a C# codebase for calls to hard-to-test static APIs and produce a ranked report showing which statics appear most frequently, which files are most affected, and which abstractions already exist in the .NET ecosystem to replace them.

When to Use

  • Auditing a project's testability before adding unit tests
  • Understanding the scope of static coupling in a legacy codebase
  • Prioritizing which statics to wrap first (highest-frequency wins)
  • Creating a migration plan for incremental testability improvements

Response Guidelines

  • Scale the response to the user's request. A question about a specific category (e.g., "find time statics") should focus on that category with file locations and counts, not produce a full report across all categories.
  • When the user provides a specific file or directory path, scan only that scope — do not expand to the entire solution unless asked.
  • The full structured report format in Step 4 is for comprehensive audit requests. For focused questions, return only the relevant subset (e.g., category summary + affected files for the requested category).

Execution Contract

  • A relative path named in the prompt is enough to start. Discover it with the

available file-listing tools and scan it immediately; do not ask the user to provide or re-upload files before both discovery and a content search fail.

  • Start with a recursive, line-numbered content search over eligible `.cs`

files. Do not search only for the `static` keyword: ambient calls inside LINQ expressions, lambdas, callbacks, and interpolated strings usually have no `static` modifier.

  • If a file-reading tool fails on a path that listing or search proved exists,

classify the failure before retrying. Fall back to another available mechanism such as `rg -n`, grep, or a shell file reader only for confirmed tool availability, transport, or path-normalization failures and only after verifying the canonical path remains inside the workspace. Stop on content-exclusion, permission/policy, workspace-boundary, or unknown failures. Search output can seed the occurrence ledger; open only the surrounding code needed to verify receiver provenance.

  • Never stop after loading this skill or announcing a scan plan. Return the

completed audit in the same response. If every fallback genuinely fails, report the verified partial findings and the exact limitation; do not invent findings or replace the audit with a request to rerun.

When Not to Use

  • The user wants wrappers generated (hand off to `generate-testability-wrappers`)
  • The user wants mechanical migration done (hand off to `migrate-static-to-wrapper`)
  • The statics are already behind interfaces or `TimeProvider`
  • The code is not C# / .NET

Inputs

| Input | Required | Description | |-------|----------|-------------| | Target path | No | A file, directory, project (.csproj), or solution (.sln) to scan. Defaults to the current workspace. | | Exclusion patterns | No | Glob patterns to skip (e.g., `**/obj/**`, `**/Migrations/**`) | | Category filter | No | Limit to specific categories: `time`, `filesystem`, `environment`, `network`, `console`, `process` |

Workflow

Step 1: Determine scan scope

Resolve the target to a set of `.cs` files:

  • Treat a prompt-named workspace-relative path as the target; locate it rather

than asking the user for an absolute path.

  • If omitted, scan every eligible `.cs` file under the current workspace; do not

pick one project and silently omit its siblings.

  • If a `.cs` file, scan that single file.
  • If a directory, scan all `.cs` files recursively (excluding `obj/`, `bin/`).
  • If a `.csproj`, find its directory and scan `.cs` files within.
  • If a `.sln`, parse it, find all project directories, and scan `.cs` files across all projects.

Always exclude `obj/`, `bin/`, and any user-specified exclusion patterns.

Step 2: Search for static dependency patterns

Scan each file for calls matching these categories:

Treat pattern matches as candidates, not findings. Before counting an instance call, trace how its receiver enters the class. A collaborator supplied through a constructor, parameter, property, or dependency injection (DI) is already a test seam. In particular, an injected `HttpClient` is testable with a controlled `HttpMessageHandler`; do not count its calls or recommend replacing it merely because the injected type is concrete.

| Category | Patterns to search for | Recommended replacement | |----------|----------------------|------------------------| | **Time** | `DateTime.Now`, `DateTime.UtcNow`, `DateTime.Today`, `DateTimeOffset.Now`, `DateTimeOffset.UtcNow`, `Task.Delay(`, `new CancellationTokenSource(TimeSpan` | `TimeProvider` (.NET 8+) | | **File System** | `File.ReadAllText(`, `File.WriteAllText(`, `File.Exists(`, `File.Delete(`, `File.Copy(`, `File.Move(`, `Directory.Exists(`, `Directory.CreateDirectory(`, `Directory.GetFiles(`, `Directory.Delete(`, `Path.GetTempPath(`, and instance members that hit the disk (`new FileInfo(...)`, `new DirectoryInfo(...)`, `.LastWriteTimeUtc`, `new StreamReader(path)`) | `IFileSystem` (System.IO.Abstractions NuGet) | | **Randomness / identity** | `new Random(`, `Random.Shared`, `Guid.NewGuid(` | `TimeProvider`-style seam:

Read more
Ships withdotnet-skills

This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.

Get the whole plugin

Other skills on dotnet-skills.