Getting Started
Kista is a framework that provides a set of abstractions and implementations of the Repository Pattern, to simplify the access to data sources in your application while keeping your domain model decoupled from any specific persistence technology.
Below you will find a quick and generic guide to start using the framework in your application.
To learn about the specific usage of the framework, you can read the following documentation:
| Topic | Description |
|---|---|
| Using the Entity Framework Core Repository | Learn how to use the Repository pattern with Entity Framework Core |
| Using the MongoDB Repository | Accessing MongoDB databases through the Repository pattern |
| Using the In-Memory Repository | Interface a volatile and in-process storage using a Repository pattern. |
| Filtering | Expression-based and Dynamic LINQ filtering with automatic service resolution |
| Filter Cache | Bounded expression caching for high-throughput Dynamic LINQ queries |
| The Entity Manager | Provide your application with a business layer on top of the Repository for additional functions (logging, validation, caching, event sourcing, etc.) |
| Repository Lifecycle | Automate repository creation, teardown, and seeding during application startup |
| Extending the Repository | Learn how to create a custom repository to access your data source, according to your specific data logic |
| Multi-Tenancy | Learn how to use the framework in a multi-tenant application |
| User Entities | Learn how to define and query entities that are scoped to a specific user |
| Sample Application | A complete ASP.NET Core reference app with lifecycle management and CRUD endpoints |
Installation
The framework is organized into a kernel package (Kista) that provides the basic interfaces and abstractions, and a set of driver packages that implement those abstractions for specific data sources.
When you install any driver package, the kernel package is automatically pulled in as a transitive dependency — you do not need to install it explicitly.
Requirements
The library targets the following .NET runtimes:
| .NET Runtime | Supported |
|---|---|
| .NET 8.0 | ✅ |
| .NET 9.0 | ✅ |
| .NET 10.0 | ✅ |
Support for .NET 6.0 and .NET 7.0 was dropped. Please ensure your project targets .NET 8.0 or later.
The Kernel Package
All driver packages are built on top of the kernel package that provides the core interfaces and abstractions. If you want to develop your own driver for a specific data source, depend only on Kista and implement the IRepository<TEntity> interface.
dotnet add package Kista
The Drivers
| Driver | Package | Description |
|---|---|---|
| In-Memory | Kista.InMemory | A volatile, in-process repository — ideal for testing and prototyping. |
| MongoDB | Kista.MongoFramework | Stores entities in a MongoDB database via MongoFramework. |
| MongoDB Multi-Tenant | Kista.MongoFramework.MultiTenant | Multi-tenant MongoDB connection management via Finbuckle.MultiTenant. |
| Entity Framework Core | Kista.EntityFramework | Stores entities in any relational database supported by Entity Framework Core. |
| EF Core Multi-Tenant | Kista.EntityFramework.MultiTenant | Multi-tenant EF Core with database-per-tenant or shared-database strategies. |
| Dynamic LINQ | Kista.DynamicLinq | Runtime string-based filter expressions via System.Linq.Dynamic.Core. |
| Entity Manager | Kista.Manager | Business layer with validation, normalization, caching, and event sourcing. |
| Entity Manager EasyCaching | Kista.Manager.EasyCaching | Second-level caching for EntityManager via EasyCaching. |
| Entity Manager ASP.NET Core | Kista.Manager.AspNetCore | ASP.NET Core integration for automatic HTTP request cancellation. |
| User Entities / Owner Scoping | Kista.Owners | Decorator-based user scoping with automatic owner assignment and query filtering. |
| Entity States | Kista.States.Core | Entity state management abstractions (experimental). |
Instrumentation
The library provides a fluent builder API via AddRepositoryContext() to configure repositories, drivers, and cross-cutting concerns in a unified way.
Using the Fluent Builder
// Program.cs
// In-Memory driver
builder.Services.AddRepositoryContext()
.UseInMemory();
// Entity Framework Core driver
builder.Services.AddRepositoryContext()
.UseEntityFramework<MyDbContext>(b => b
.ConfigureDbContext(opts => opts.UseSqlServer("...")));
// MongoDB driver
builder.Services.AddRepositoryContext()
.UseMongoDB<MyMongoContext>(b => b
.WithConnectionString("mongodb://..."));
Each Use*() method registers open-generic repository types (InMemoryRepository<>, EntityRepository<>, MongoRepository<>) with the DI container. This means IRepository<AnyEntity> resolves automatically — you do not need to write a repository class for every entity type. When you also register a concrete repository via AddRepository<MyRepo>(), the closed generic takes precedence over the open generic for that specific entity, letting you mix bulk defaults with per-entity customization.
Each driver call returns to the parent builder, allowing you to chain multiple concerns:
builder.Services.AddRepositoryContext()
.UseEntityFramework<AppDbContext>(b => b
.ConfigureDbContext(opts => opts.UseSqlServer("...")))
.WithManagement()
.WithEasyCaching();
Assembly Scanning
Use ScanRepositories() to automatically discover and register repository types from one or more assemblies:
builder.Services.AddRepositoryContext()
.UseInMemory()
.ScanRepositories(typeof(MyEntityRepository).Assembly);
Open generic repositories are registered as open generics; closed repositories are registered via their service interfaces.
Legacy Registration
The older AddRepository<T> extension method is still available for backward compatibility:
builder.Services.AddRepository<InMemoryRepository<MyEntity>>();
Note:
AddRepository<T>is marked[Obsolete]but not as an error. It will continue to work. PreferAddRepositoryContext()for new code.
Consuming the Repository
After registration, the following service types become available in the DI container (availability depends on which interfaces the concrete repository implements):
| Service | Description |
|---|---|
MyCustomRepository | The concrete repository implementation. |
IRepository<MyEntity> | Core CRUD, key-based look-up (FindAsync), and unsorted pagination (GetPageAsync). |
IMyCustomRepository | The custom interface (if defined) that extends IRepository<MyEntity> with domain-specific query methods. |
ITrackingRepository<MyEntity> | Change-tracking queries (if implemented). |
Note: The legacy extension interfaces
IQueryableRepository,IPageableRepository, andIFilterableRepositoryare deprecated. Query capabilities are now provided throughprotectedmembers ofRepository<TEntity, TKey>and should be exposed via domain-specific methods on your custom repository interface. See The Repository Pattern and Customize the Repository for details.