module Analyzer::CSharp::Common

Direct including types

Defined in:

analyzer/analyzers/csharp/common.cr

Constant Summary

KNOWN_SERVICE_TYPES = Set {"CancellationToken", "HttpContext", "HttpRequest", "HttpResponse", "ClaimsPrincipal", "IServiceProvider", "LinkGenerator", "ILoggerFactory", "IConfiguration", "IWebHostEnvironment", "IHostEnvironment"}

Concrete framework types that are always resolved from DI / the request pipeline rather than bound from user input.

SERVICE_FORM_INPUT_TYPES = Set {"IFormFile", "IFormFileCollection", "IFormCollection"}

IFormFile/IFormFileCollection/IFormCollection are interfaces but bind from the request body (file upload / form), not from DI — keep them as request inputs even though they match the interface rule below.

SERVICE_TYPE_SUFFIXES = ["Repository", "Service", "Services", "Manager", "Mediator", "Mapper", "Accessor", "Dispatcher", "Publisher", "DbContext", "Context", "Logger"] of ::String

High-precision suffixes that mark a type as a dependency-injected collaborator. Deliberately conservative: suffixes that collide with common domain/entity names (e.g. Client, Provider, Factory) are left out so request DTOs aren't dropped by mistake. Interface-typed DI is caught separately by the I<Pascal> rule.

Class Method Summary

Class Method Detail

def self.csharp_service_type?(type_name : String) : Bool #

Heuristic for whether a parameter's type names a dependency-injected service (DbContext, repository, MediatR sender, mapper, …) rather than a value bound from the request. ASP.NET Core can't be statically resolved against its DI container, so we lean on near-universal naming conventions in real code:

  • Interfaces (I + PascalCase) are never deserialized from a request body and never bound from the query string — they're DI or special pipeline types. The [a-z] third-char guard keeps acronym value types like IPAddress (I-P-A) out of the net.
  • A small set of concrete framework types and service suffixes.

Returns false for the form-upload interfaces, which are request inputs.


[View source]
def self.csharp_test_path?(path : String) : Bool #

Standard .NET test-source conventions:

  • /test/ and /tests/ parent directories — Microsoft's own repos park unit + integration tests under src/<Project>/test/... (aspnetcore) or tests/... (smaller solutions).
  • /testassets/ — aspnetcore's helper-controller convention for spinning up a real server inside the test harness.
  • Tests.cs / Test.cs filename — xUnit / NUnit / MSTest suffix convention.

dotnet/aspnetcore alone parks ~3,600 phantom endpoints under src/Mvc/test/... and similar trees. Production code never adopts any of these.


[View source]