NP0006: A data-access abstraction is called once per element and its implementation is not visible
Default severity: Info (a suggestion in the IDE; not shown in command-line builds unless raised)
What it detects
A call, once per element, to a method that looks like data access but whose body the analyzer cannot see: an
interface or abstract method without an implementation in the project, or a method of a referenced assembly. In
Clean Architecture the application layer calls IOrderRepository, and the implementation lives in an infrastructure
project it does not reference, so NP0001 cannot prove the call queries.
Projects built with the package write summaries of their methods into their assemblies, so calls into a referenced project are followed and reported as NP0001 when they query; NP0006 is left for what no summary covers: an implementation in a project the caller does not reference, or a library built without the package.
A method "looks like data access" when its type matches nplusone.data_access_types (default
*Repository;*Repo;*Store;*Dao;*DataAccess;*QueryService;*Queries) and it returns a value (methods that return
nothing or a bare Task are commands, not lookups).
foreach (var id in ids)
{
var customer = await customers.GetByIdAsync(id); // NP0006 (ICustomerRepository's implementation is elsewhere)
}
How to make it precise
-
Declare the methods that query in
nplusone.query_methods; their calls then report NP0001 as a warning:# .globalconfigis_global = truenplusone.query_methods = MyApp.Application.Abstractions.I*Repository.* -
Declare cached or in-memory lookups in
nplusone.ignored_methods. -
Raise NP0006 to a warning when your repositories follow the naming convention:
dotnet_diagnostic.NP0006.severity = warning.
How to fix it
Add a method that loads all elements at once (GetByIdsAsync(ids)) and call it before the loop.