https://github.com/ignaciocastro0713/specification.lite
Specification.Lite is a library for implementing Specification pattern in .NET applications.
https://github.com/ignaciocastro0713/specification.lite
csharp dotnet net8 specification
Last synced: 3 months ago
JSON representation
Specification.Lite is a library for implementing Specification pattern in .NET applications.
- Host: GitHub
- URL: https://github.com/ignaciocastro0713/specification.lite
- Owner: IgnacioCastro0713
- License: mit
- Created: 2025-06-29T18:22:17.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-06-29T19:27:55.000Z (about 1 year ago)
- Last Synced: 2025-06-29T19:30:32.134Z (about 1 year ago)
- Topics: csharp, dotnet, net8, specification
- Language: C#
- Homepage:
- Size: 15.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Specification.Lite

[](https://www.nuget.org/packages/Specification.Lite)
[](https://www.nuget.org/packages/Specification.Lite)
[](https://github.com/IgnacioCastro0713/Specification.Lite/blob/main/LICENSE)
**Specification.Lite** is a lightweight .NET library that streamlines the implementation of the Specification pattern. It helps you encapsulate, reuse, and combine business rules, predicates, and query logic in a flexible and maintainable way.
---
## Features
- **Specification Pattern:**
Define reusable business rules and query logic using strongly-typed specifications. Encapsulate complex predicates into composable objects.
- **Query Extensions:**
Apply specifications directly to `IQueryable` objects for filtering, ordering, and projecting data. Supports asynchronous LINQ operations like `ToListAsync`, `FirstOrDefaultAsync`, `SingleOrDefaultAsync`, and `AnyAsync`.
- **Include Expressions:**
Eagerly load related entities in queries using `Include` and `ThenInclude`, just like in Entity Framework.
- **Ordering:**
Easily apply ordering to queries with `OrderBy` and `OrderByDescending` methods on your specifications.
- **Projection:**
Transform entities to DTOs or other result types within the specification using `Select` and `SelectMany`.
- **Skip & Take:**
Effortlessly paginate query results using `Skip` and `Take` inside your specifications.
- **Tracking:**
Control whether entities are tracked by the context with `AsTracking`, `AsNoTracking` and `AsNoTrackingWithIdentityResolution` for optimal performance.
- **SplitQuery:**
Enables the use of EF Core’s `AsSplitQuery` to optimize queries containing multiple includes, preventing the cartesian explosion problem.
- **IgnoreQueryFilters:**
Allows you to bypass global query filters (such as soft delete or multi-tenancy) by applying `IgnoreQueryFilters` in your specifications.
- **IgnoreAutoIncludes:**
Prevents Entity Framework Core from automatically applying `Include` statements configured in the model by using `IgnoreAutoIncludes` in your specifications. This gives you full control over which related entities are included in your queries.
- **WithTag:**
Annotate queries with a custom tag using `WithTag` to improve query diagnostics and debugging. This is especially useful for identifying specific queries in logs or performance monitoring tools.
- **Entity Framework Integration:**
Seamlessly integrates with Entity Framework Core, making it easy to use specifications in your repositories or DbContext queries.
---
## Installation
Install via NuGet Package Manager:
```pwsh
dotnet add package Specification.Lite --version 1.3.0
```
Or add to your project file:
```xml
```
---
## Usage Examples
### Simple Example
Define a basic specification and use it to query active users:
```csharp
// Define a simple specification for active users
public class ActiveUsersSpecification : Specification
{
public ActiveUsersSpecification()
{
Query
.Include(u => u.Orders)
.Where(user => user.IsActive);
}
}
// Usage in your repository or DbContext
var spec = new ActiveUsersSpecification();
var activeUsers = await dbContext.Users.WithSpecification(spec).ToListAsync();
// Or directly using the DbContext
var activeUsers = await dbContext.Users.ToListAsync(spec);
```
---
### Complex Example
Combine filtering, includes, ordering, projection, pagination, split queries, ignoring query filters, and no-tracking:
```csharp
// Complex specification: Get all active users who registered after 2024-01-01,
// include their orders (with order items), ordered by registration date descending,
// project to a custom DTO, paginate results, use split queries, ignore global query filters, and return as no-tracking.
public class RecentActiveUsersWithOrdersSpec : Specification
{
public RecentActiveUsersWithOrdersSpec(DateTime since, int skip, int take)
{
Query
.TagWith("Tag in spec query")
.Where(u => u.IsActive && u.RegisteredAt >= since)
.Include(u => u.Orders)
.ThenInclude(o => o.OrderItems)
.OrderByDescending(u => u.RegisteredAt)
.Skip(skip)
.Take(take)
.AsNoTracking()
.AsSplitQuery()
.IgnoreQueryFilters()
.Select(u => new UserSummaryDto
{
Id = u.Id,
Name = u.Name,
OrderCount = u.Orders.Count,
TotalSpent = u.Orders.Sum(o => o.TotalAmount)
});
}
}
// Usage in your application code
var spec = new RecentActiveUsersWithOrdersSpec(new DateTime(2024, 1, 1), skip: 20, take: 10);
var summaries = await dbContext.Users.WithSpecification(spec).ToListAsync();
// Or directly using the DbContext
var summaries = await dbContext.Users.ToListAsync(spec);
```
See the [examples folder](./examples).
---
## Contributing
Contributions, issues, and feature requests are welcome! or open an issue to get started.