|
5 | 5 | [](https://f.feedz.io/foundatio/foundatio/packages/Foundatio.Repositories/latest/download) |
6 | 6 | [](https://discord.gg/6HxgFCx) |
7 | 7 |
|
8 | | -Generic repository contract and implementations. Currently only implemented for Elasticsearch, but there are plans for other implementations. |
9 | | - |
10 | | -# Features |
11 | | - |
12 | | -- Simple document repository pattern |
13 | | - - CRUD operations: Add, Save, Remove, Get |
14 | | -- Supports patch operations |
15 | | - - JSON patch |
16 | | - - Partial document patch |
17 | | - - Painless script patch (Elasticsearch) |
18 | | - - Can be applied in bulk using queries |
19 | | -- Async events that can be wired up and listened to outside of the repos |
20 | | -- Caching (real-time invalidated before save and stored in distributed cache) |
21 | | -- Message bus support (enables real-time apps sends messages like doc updated up to the client so they know to update the UI) |
22 | | -- Searchable that works with Foundatio.Parsers lib for dynamic querying, filtering, sorting and aggregations |
23 | | -- Document validation |
24 | | -- Document versioning |
25 | | -- Soft deletes |
26 | | -- Auto document created and updated dates |
27 | | -- Document migrations |
28 | | -- Elasticsearch implementation |
29 | | - - Plan to add additional implementations (Postgres with Marten would be a good fit) |
30 | | -- Elasticsearch index configuration allows simpler and more organized configuration |
31 | | - - Schema versioning |
32 | | - - Parent child queries |
33 | | - - Daily and monthly index strategies |
34 | | -- Supports different consistency models (immediate, wait or eventual) |
35 | | - - Can be configured at the index type or individual query level |
36 | | -- Query builders used to make common ways of querying data easier and more portable between repo implementations |
37 | | -- Can still use raw Elasticsearch queries |
38 | | -- Field includes and excludes to make the response size smaller |
39 | | -- Field conditions query builder |
40 | | -- Paging including snapshot paging support |
41 | | -- Dynamic field resolution for using friendly names of dynamically generated fields |
42 | | -- Jobs for index maintenance, snapshots, reindex |
43 | | -- Strongly typed field access (using lambda expressions) to enable refactoring |
| 8 | +# Foundatio.Repositories |
| 9 | + |
| 10 | +A production-grade repository pattern library for .NET with Elasticsearch implementation. Built on [Foundatio](https://github.com/FoundatioFx/Foundatio) building blocks, it provides a clean abstraction over data access with powerful features like caching, messaging, soft deletes, and versioning. |
| 11 | + |
| 12 | +📖 **[Full Documentation](https://repositories.foundatio.dev)** |
| 13 | + |
| 14 | +## Installation |
| 15 | + |
| 16 | +```bash |
| 17 | +dotnet add package Foundatio.Repositories.Elasticsearch |
| 18 | +``` |
| 19 | + |
| 20 | +## Quick Start |
| 21 | + |
| 22 | +### 1. Define Your Entity |
| 23 | + |
| 24 | +```csharp |
| 25 | +using Foundatio.Repositories.Models; |
| 26 | + |
| 27 | +public class Employee : IIdentity, IHaveDates, ISupportSoftDeletes |
| 28 | +{ |
| 29 | + public string Id { get; set; } = string.Empty; |
| 30 | + public string Name { get; set; } = string.Empty; |
| 31 | + public string Email { get; set; } = string.Empty; |
| 32 | + public int Age { get; set; } |
| 33 | + public DateTime CreatedUtc { get; set; } |
| 34 | + public DateTime UpdatedUtc { get; set; } |
| 35 | + public bool IsDeleted { get; set; } |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +### 2. Create Index Configuration |
| 40 | + |
| 41 | +```csharp |
| 42 | +using Foundatio.Repositories.Elasticsearch.Configuration; |
| 43 | + |
| 44 | +public sealed class EmployeeIndex : VersionedIndex<Employee> |
| 45 | +{ |
| 46 | + public EmployeeIndex(IElasticConfiguration configuration) |
| 47 | + : base(configuration, "employees", version: 1) { } |
| 48 | + |
| 49 | + public override TypeMappingDescriptor<Employee> ConfigureIndexMapping( |
| 50 | + TypeMappingDescriptor<Employee> map) |
| 51 | + { |
| 52 | + return map |
| 53 | + .Dynamic(false) |
| 54 | + .Properties(p => p |
| 55 | + .SetupDefaults() |
| 56 | + .Text(f => f.Name(e => e.Name).AddKeywordAndSortFields()) |
| 57 | + .Text(f => f.Name(e => e.Email).AddKeywordAndSortFields()) |
| 58 | + .Number(f => f.Name(e => e.Age).Type(NumberType.Integer)) |
| 59 | + ); |
| 60 | + } |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +### 3. Create Repository |
| 65 | + |
| 66 | +```csharp |
| 67 | +using Foundatio.Repositories; |
| 68 | +using Foundatio.Repositories.Elasticsearch; |
| 69 | + |
| 70 | +public interface IEmployeeRepository : ISearchableRepository<Employee> { } |
| 71 | + |
| 72 | +public class EmployeeRepository : ElasticRepositoryBase<Employee>, IEmployeeRepository |
| 73 | +{ |
| 74 | + public EmployeeRepository(MyElasticConfiguration configuration) |
| 75 | + : base(configuration.Employees) { } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +### 4. Use the Repository |
| 80 | + |
| 81 | +```csharp |
| 82 | +// Add |
| 83 | +var employee = await repository.AddAsync(new Employee |
| 84 | +{ |
| 85 | + Name = "John Doe", |
| 86 | + Email = "john@example.com", |
| 87 | + Age = 30 |
| 88 | +}); |
| 89 | + |
| 90 | +// Query |
| 91 | +var results = await repository.FindAsync(q => q |
| 92 | + .FilterExpression("age:>=25") |
| 93 | + .SortExpression("name")); |
| 94 | + |
| 95 | +// Update |
| 96 | +employee.Age = 31; |
| 97 | +await repository.SaveAsync(employee); |
| 98 | + |
| 99 | +// Soft delete |
| 100 | +employee.IsDeleted = true; |
| 101 | +await repository.SaveAsync(employee); |
| 102 | + |
| 103 | +// Hard delete |
| 104 | +await repository.RemoveAsync(employee); |
| 105 | +``` |
| 106 | + |
| 107 | +## Features |
| 108 | + |
| 109 | +### Repository Pattern |
| 110 | +- **`IReadOnlyRepository<T>`** - Read operations (Get, Find, Count, Exists) |
| 111 | +- **`IRepository<T>`** - Write operations (Add, Save, Remove, Patch) |
| 112 | +- **`ISearchableRepository<T>`** - Dynamic querying with filters, sorting, and aggregations |
| 113 | + |
| 114 | +### Patch Operations |
| 115 | +- **JSON Patch** - RFC 6902 compliant patch operations |
| 116 | +- **Partial Patch** - Update specific fields without loading the full document |
| 117 | +- **Script Patch** - Elasticsearch Painless scripts for complex updates |
| 118 | +- **Bulk Patching** - Apply patches to multiple documents via query |
| 119 | + |
| 120 | +### Caching |
| 121 | +- Built-in distributed caching with automatic invalidation |
| 122 | +- Real-time cache consistency via message bus |
| 123 | +- Configurable cache expiration and custom cache keys |
| 124 | + |
| 125 | +### Message Bus |
| 126 | +- Entity change notifications (`EntityChanged` messages) |
| 127 | +- Real-time updates for event-driven architectures |
| 128 | +- Soft delete transition detection (`ChangeType.Removed`) |
| 129 | + |
| 130 | +### Soft Deletes |
| 131 | +- Automatic query filtering based on `IsDeleted` |
| 132 | +- Three query modes: `ActiveOnly`, `DeletedOnly`, `All` |
| 133 | +- Restore capability for soft-deleted documents |
| 134 | + |
| 135 | +### Document Versioning |
| 136 | +- Optimistic concurrency control |
| 137 | +- Automatic version conflict detection |
| 138 | +- Retry patterns for conflict resolution |
| 139 | + |
| 140 | +### Index Management |
| 141 | +- **`Index<T>`** - Basic index configuration |
| 142 | +- **`VersionedIndex<T>`** - Schema versioning with migrations |
| 143 | +- **`DailyIndex<T>`** - Time-series with daily partitioning |
| 144 | +- **`MonthlyIndex<T>`** - Time-series with monthly partitioning |
| 145 | + |
| 146 | +### Event System |
| 147 | +- `DocumentsAdding` / `DocumentsAdded` |
| 148 | +- `DocumentsSaving` / `DocumentsSaved` |
| 149 | +- `DocumentsRemoving` / `DocumentsRemoved` |
| 150 | +- `DocumentsChanging` / `DocumentsChanged` |
| 151 | +- `BeforeQuery` - Query interception |
| 152 | +- `BeforePublishEntityChanged` - Notification interception |
| 153 | + |
| 154 | +### Additional Features |
| 155 | +- Document validation with custom validators |
| 156 | +- Migrations for data schema evolution |
| 157 | +- Jobs for index maintenance, snapshots, and cleanup |
| 158 | +- Custom fields for tenant-specific data |
| 159 | +- Parent-child document relationships |
| 160 | +- Aggregations and analytics |
| 161 | + |
| 162 | +## Documentation |
| 163 | + |
| 164 | +Visit the [full documentation](https://repositories.foundatio.dev) for detailed guides: |
| 165 | + |
| 166 | +- [Getting Started](https://repositories.foundatio.dev/guide/getting-started) |
| 167 | +- [Repository Pattern](https://repositories.foundatio.dev/guide/repository-pattern) |
| 168 | +- [Elasticsearch Setup](https://repositories.foundatio.dev/guide/elasticsearch-setup) |
| 169 | +- [CRUD Operations](https://repositories.foundatio.dev/guide/crud-operations) |
| 170 | +- [Querying](https://repositories.foundatio.dev/guide/querying) |
| 171 | +- [Configuration](https://repositories.foundatio.dev/guide/configuration) |
| 172 | +- [Validation](https://repositories.foundatio.dev/guide/validation) |
| 173 | +- [Caching](https://repositories.foundatio.dev/guide/caching) |
| 174 | +- [Message Bus](https://repositories.foundatio.dev/guide/message-bus) |
| 175 | +- [Patch Operations](https://repositories.foundatio.dev/guide/patch-operations) |
| 176 | +- [Soft Deletes](https://repositories.foundatio.dev/guide/soft-deletes) |
| 177 | +- [Versioning](https://repositories.foundatio.dev/guide/versioning) |
| 178 | +- [Index Management](https://repositories.foundatio.dev/guide/index-management) |
| 179 | +- [Migrations](https://repositories.foundatio.dev/guide/migrations) |
| 180 | +- [Jobs](https://repositories.foundatio.dev/guide/jobs) |
| 181 | +- [Custom Fields](https://repositories.foundatio.dev/guide/custom-fields) |
| 182 | + |
| 183 | +## Sample Application |
| 184 | + |
| 185 | +See the [sample Blazor application](samples/Foundatio.SampleApp) for a complete working example. |
| 186 | + |
| 187 | +## Related Projects |
| 188 | + |
| 189 | +- [Foundatio](https://github.com/FoundatioFx/Foundatio) - Core building blocks (caching, messaging, queues, jobs) |
| 190 | +- [Foundatio.Parsers](https://github.com/FoundatioFx/Foundatio.Parsers) - Query parsing for dynamic filtering |
| 191 | + |
| 192 | +## Contributing |
| 193 | + |
| 194 | +We welcome contributions! Please see our [contributing guidelines](CONTRIBUTING.md) for details. |
| 195 | + |
| 196 | +## License |
| 197 | + |
| 198 | +Licensed under the Apache License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details. |
0 commit comments