VOOZH about

URL: https://docs.revoframework.net/reference-guide/data-persistence.md


> For the complete documentation index, see [llms.txt](https://docs.revoframework.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.revoframework.net/reference-guide/data-persistence.md). # Data persistence ## Repositories Revo framework offers a number of facilities for working with entities and their persistence. Repositories are one of the core concepts in framework’s data persistence. There are two distinct types of repositories that a developer can use. Both of them come with a certain level of implementation abstraction. ### Aggregate repository In terms of domain-driven design, `IRepository` (defined in Revo.Infrastructure module) is the high-level repository that would be used in the command handlers for the write side of the application working with the domain model. {% hint style="info" %} The implementation of `IRepository` interface is not bound to any specific database system backend (or an ORM library) and instead delegates most of the actual data-persistence related responsibilities to different *aggregate stores -* i.e. **event sourced aggregate store** or **CRUD aggregate store**. The repository itself is then just a thin wrapper over those aggregate stores, making it easier to work with aggregate stored in different persistence backends by providing a single unified API for them while also handing some of the concepts related to domain repositories – like the unit-of-work pattern and event publishing. {% endhint %} The repository declares all methods as generic, simplifying all repository interactions to just one universal interface. When querying for an entity, the repository itself then tries to deduce the aggregate store it belongs. When the correct aggregate store is found, the repository delegates the actual persistence work (loading, saving, querying…) to it. To enforce aggregate consistency boundaries on compliance with DDD rules, repositories only allow working with aggregate roots, which is enforced by generic type constraints for all its generic methods (requiring any `IAggregateRoot` descendant). This prevents breaking the encapsulation of aggregates by querying and manually modifying single aggregate entities separately. Following abridged code snippet of `IRepository` interface definition shows some of the basic functionality it offers for working with aggregates. ```csharp public interface IRepository : IUnitOfWorkProvider, IDisposable { void Add