# LS2011: Query Handler Takes a Repository

## Intent

LS2011 is a compiler check that reports a query handler, the type that answers a read, taking a Domain repository in its constructor, which pulls an aggregate into a read that should project past it. This page states what the rule reports, where the error sits, and how to reach read data through the read session.

## Reference

### What the Rule Enforces

LS2011 enforces [Project queries directly](https://litespec.dev/4.0.0/backend/application.md#project-queries-directly) (`litespec/backend/application#project-queries-directly`). It runs in Application, Infrastructure, and Worker. Its category is `LiteSpec.Layers`. Severity and enablement follow the [Analyzers overview](https://litespec.dev/4.0.0/analyzers/README.md).

### What the Rule Reports

The rule reports a query handler, which is a class whose name ends in `QueryHandler` or that implements `IQueryHandler`, that takes a constructor parameter whose type is an interface named `I*Repository`. The diagnostic sits on the parameter type, and its message names the handler and the repository.

### Failing Example

```csharp
internal sealed class ListLoansQueryHandler(ILoanRepository loanRepository)
{
}
```

### Passing Example

```csharp
internal sealed class ListLoansQueryHandler(IQuerySession session)
{
}
```

### How to Fix

Project the read through the read session the handler takes as a constructor parameter, applying filter, scope, ordering, and limit before materialization.

Where the repository read a table kept beside the documents, such as a counter or a ledger written through plain SQL, move its SQL into the handler as a session query that selects one JSON object per row, as [Query Through IQuerySession](https://litespec.dev/4.0.0/backend/dotnet/persistence.md#query-through-iquerysession) shows. Do not add a read interface in the repository's place.

## Notes

### What the Rule Ignores

The rule does not report a command handler taking a repository, a query handler taking any other type, or a repository passed outside a constructor. It does not report a parameter whose type is a concrete repository class. It does not run in Domain or WebApi.
