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.
IAggregateRootdescendant). This prevents breaking the encapsulation of aggregates by querying and manually modifying single aggregate entities separately.
IRepositoryinterface definition shows some of the basic functionality it offers for working with aggregates.
IQueryableEntityinterface (this interface is empty and serves just to signify what entities can be used in those queries). For example, this means while these methods will be available for aggregate roots stored in a RDBMS and accessed via Entity Framework (generally any
BasicAggregateRoot-derived aggregate roots), they will not be available for event sourced aggregate roots because event store usually do not possess these kinds of querying features.
ICrudRepositorywhich is contained in Revo.DataAccess module) represent a way of a more direct way of accessing database. Unlike the aggregate repository (
IRepository), it is not burdened with domain concepts like aggregate consistency boundaries and encapsulation and provides more flexibility when working with data. Where IRepository offered only basic functionality for working with entities to abstract from the underlying technology,
ICrudRepositorystrives to do the opposite and offer maximum of the features that the used database (or an ORM) has while still maintaining some minimum level of abstraction in order to enable easy testing. Having said that, it is important to emphasize that they serve a completely different purpose – while the aggregate IRepository would usually be used on the write side of the application in command handlers to update the domain, the CRUD repository will mostly be used just for efficient access to read models in projectors and query handlers and in other places that are not encumbered by the complex business rules handled by the domain model.
ICrudRepositoryinterfaces relies heavily on the use of
IQueryable<T>support of the .NET platform. This enables to perform arbitrary queries on the database without bloating the interface definition with a huge number of different query methods or a need for custom repositories for every specific, saving a lot of developer’s time, while still also providing type safety and the safety of compile-time checks to a certain degree.
ICrudRepositoryis actually defined in a base type named
IReadRepository. This base type does not allow any modifications to the entities (i.e. it has no save or add/remove methods), which means it is very suitable in situations when we want to limit the operations an object can do with entities in the repository – for example in a query handler that should always only performs reads of the database. It also potentially makes testing those entities easier.
ICrudRepositoryin order to facilitate the use of the features specific to its technology (for example,
IEFCoreCrudRepositorymaking it possible to directly work with some of the EF Core ORM features).