# Persistence

#### Motivation

> A *repository* represents all objects of a certain type as a conceptual set (usually emulated). **It acts like a collection**, except with more elaborate querying capability. \[...] For each type of object that needs global access, **create an object that can provide the illusion of an in-memory collection** of all objects of that type.\
> \
> \&#xNAN;***Eric Evans - Domain Driven Design***

Most repository patterns contain many query methods, and they are often nearly identical to the DbContext class. Unlike the norm, the Eiffel framework follows a collection-oriented repository approach."

Each repository should expose a single aggregate, and the maintenance of the entities or value objects should be handled by the owner aggregate.<br>

```csharp
/// <summary>
/// IRepository interface
/// </summary>
/// <typeparam name="TAggregate">The type of aggregate</typeparam>
/// <typeparam name="TIdentity">The tpye of aggregate identity</typeparam>
/// <typeparam name="TKey">The type of database primary key</typeparam>
public interface IRepository<TAggregate, TIdentity, TKey>
    where TKey : struct, IEquatable<TKey>
    where TIdentity : class
    where TAggregate : Aggregate<TIdentity, TKey>
{
    /// <summary>
    /// Gets record from database
    /// </summary>
    /// <param name="identity">Aggregate</param>
    /// <param name="cancellationToken">Cancellation token</param>
    Task<TAggregate> GetAsync(TIdentity identity, CancellationToken cancellationToken = default);

    /// <summary>
    /// Adds record to database
    /// </summary>
    /// <param name="aggregate">Aggregate identifier</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Record from database</returns>
    Task AddAsync(TAggregate aggregate, CancellationToken cancellationToken = default);


    /// <summary>
    /// Commit changes to database
    /// </summary>
    /// <param name="aggregate">Aggregate</param>
    /// <param name="cancellationToken">Cancellation token</param>
    Task SaveChangesAsync(TAggregate aggregate, CancellationToken cancellationToken = default);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.eiffel.dev/fundamentals/persistence.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
