https://github.com/bobobass84/bb84.entityframeworkcore
A reusable repository pattern in ASP.NET Core. Contains commonly used entity abstractions, their default implementations and repository abstractions with their default implementations.
https://github.com/bobobass84/bb84.entityframeworkcore
csharp ef-core entity-framework-core library
Last synced: 4 months ago
JSON representation
A reusable repository pattern in ASP.NET Core. Contains commonly used entity abstractions, their default implementations and repository abstractions with their default implementations.
- Host: GitHub
- URL: https://github.com/bobobass84/bb84.entityframeworkcore
- Owner: BoBoBaSs84
- License: mit
- Created: 2024-04-03T14:00:19.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-15T05:31:34.000Z (about 1 year ago)
- Last Synced: 2025-04-18T17:19:24.871Z (about 1 year ago)
- Topics: csharp, ef-core, entity-framework-core, library
- Language: C#
- Homepage: https://bobobass84.github.io/BB84.EntityFrameworkCore/
- Size: 13.7 MB
- Stars: 3
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# BB84.EntityFrameworkCore
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/actions/workflows/ci.yml)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/actions/workflows/cd.yml)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/actions/workflows/github-code-scanning/codeql)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/actions/workflows/dependabot/dependabot-updates)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/issues)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/commit/main)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/blob/main/LICENSE)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore)
[](https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore/releases/latest)
## 🧭 Overview
**BB84.EntityFrameworkCore** is a comprehensive .NET 8.0 & .NET 10.0 library that provides a reusable repository pattern implementation for ASP.NET Core applications. The library offers commonly used entity abstractions, their default implementations, and repository abstractions with their corresponding implementations, specifically designed to work seamlessly with Entity Framework Core.
### Key Features
- **Generic Repository Pattern**: Complete implementation of the repository pattern with CRUD operations
- **Entity Abstractions**: Pre-built interfaces for common entity types (Identity, Audited, Composite, etc.)
- **SQL Server Integration**: Specialized configurations and extensions for SQL Server
- **Auditing Support**: Built-in support for creation and modification tracking
- **Soft Delete**: Integrated soft delete functionality
- **Concurrency Control**: Built-in optimistic concurrency support
- **Type Safety**: Strongly typed implementations with generic constraints
### Target Framework
- **.NET 8.0** - LTS support until November 2026
- **.NET 10.0** - Latest LTS version of .NET
## 🏗 Project Structure
```
BB84.EntityFrameworkCore/
├── src/ # Source code
│ ├── BB84.EntityFrameworkCore.Entities.Abstractions/ # Entity interfaces
│ ├── BB84.EntityFrameworkCore.Entities/ # Entity implementations
│ ├── BB84.EntityFrameworkCore.Repositories.Abstractions/ # Repository interfaces
│ ├── BB84.EntityFrameworkCore.Repositories/ # Repository implementations
│ └── BB84.EntityFrameworkCore.Repositories.SqlServer/ # SQL Server specific features
├── tests/ # Unit tests
│ ├── BB84.EntityFrameworkCore.Entities.Tests/
│ └── BB84.EntityFrameworkCore.Repositories.Tests/
├── docs/ # Documentation
├── Directory.Build.props # Build configuration
├── Directory.Packages.props # Package management
└── BB84.EntityFrameworkCore.sln # Solution file
```
## 📦 Package Architecture
The project is organized into five distinct NuGet packages, each serving a specific purpose:
### BB84.EntityFrameworkCore.Entities.Abstractions
**Purpose**: Core entity interface definitions
**Dependencies**: None
This package contains the fundamental interfaces that define the contract for different types of entities:
- `IIdentityEntity` - Entities with unique identifiers
- `IAuditedEntity` - Entities with creation/modification tracking
- `IFullAuditedEntity` - Entities with full audit trails including soft delete
- `ICompositeEntity` - Entities with composite keys
- `IEnumeratorEntity` - Entities representing enumeration values
**Component Interfaces**:
- `IIdentity` - Provides unique identification
- `IConcurrency` - Provides optimistic concurrency control
- `ITimeAudited` - Tracks creation and modification timestamps
- `IUserAudited` - Tracks user information for auditing
- `ISoftDeletable` - Provides soft delete functionality
### BB84.EntityFrameworkCore.Entities
**Purpose**: Default implementations of entity abstractions
**Dependencies**: BB84.EntityFrameworkCore.Entities.Abstractions
Provides concrete implementations of the entity interfaces:
- `IdentityEntity` - Base class for entities with identity
- `AuditedEntity` - Base class for audited entities
- `FullAuditedEntity` - Base class for fully audited entities
- `CompositeEntity` - Base class for composite key entities
- `EnumeratorEntity` - Base class for enumeration entities
### BB84.EntityFrameworkCore.Repositories.Abstractions
**Purpose**: Repository interface definitions
**Dependencies**:
- BB84.EntityFrameworkCore.Entities.Abstractions
- Microsoft.EntityFrameworkCore.Relational (9.0.6)
Core repository interfaces:
- `IDbContext` - Database context abstraction
- `IGenericRepository` - Generic CRUD operations
- `IIdentityRepository` - Repository for identity-based entities
- `IEnumeratorRepository` - Repository for enumeration entities
### BB84.EntityFrameworkCore.Repositories
**Purpose**: Default repository implementations
**Dependencies**:
- BB84.EntityFrameworkCore.Entities
- BB84.EntityFrameworkCore.Repositories.Abstractions
Concrete repository implementations:
- `GenericRepository` - Base repository with common operations
- `IdentityRepository` - Repository for identity entities
- `EnumeratorRepository` - Repository for enumerator entities
### BB84.EntityFrameworkCore.Repositories.SqlServer
**Purpose**: SQL Server specific configurations and extensions
**Dependencies**: BB84.EntityFrameworkCore.Repositories
SQL Server specific features:
- **Configurations**: Entity type configurations for different entity types
- **Extensions**: Extension methods for Entity Framework configurations
- **Interceptors**: Database interceptors for auditing and soft delete
## 💭 Core Concepts
### Entity Hierarchy
The library follows a hierarchical approach to entity design:
```
IIdentityEntity
├── IAuditedEntity
│ └── IFullAuditedEntity
├── ICompositeEntity
│ └── IAuditedCompositeEntity
└── IEnumeratorEntity
```
### Repository Pattern
The repository pattern implementation provides:
- **Separation of Concerns**: Business logic separated from data access
- **Testability**: Easy mocking and unit testing
- **Consistency**: Standardized data access patterns
- **Flexibility**: Support for different entity types and requirements
## ✨ Entity Abstractions
### Identity Entities
Identity entities represent the most basic entity type with a unique identifier and concurrency control.
```csharp
public interface IIdentityEntity : IIdentity, IConcurrency
where TKey : IEquatable
{
// Inherits:
// TKey Id { get; set; } // From IIdentity
// byte[]? Timestamp { get; set; } // From IConcurrency
}
// Default implementation with Guid
public interface IIdentityEntity : IIdentityEntity
```
**Key Features**:
- Unique identifier of specified type
- Optimistic concurrency control via timestamp
- Base interface for all other entity types
### Audited Entities
Audited entities extend identity entities with creation and modification tracking.
```csharp
public interface IAuditedEntity :
IIdentityEntity, IUserAudited
where TKey : IEquatable
where TCreator : notnull
{
// Inherits from IIdentityEntity:
// TKey Id { get; set; }
// byte[]? Timestamp { get; set; }
// Inherits from IUserAudited:
// TCreator CreatedBy { get; set; }
// TEdited? EditedBy { get; set; }
// DateTimeOffset CreatedAt { get; set; }
// DateTimeOffset? EditedAt { get; set; }
}
```
**Convenience Overloads**:
```csharp
// Default string-based user types
public interface IAuditedEntity : IAuditedEntity
// Default Guid key with string users
public interface IAuditedEntity : IAuditedEntity
```
### Full Audited Entities
Full audited entities include soft delete capabilities in addition to standard auditing.
```csharp
public interface IFullAuditedEntity :
IAuditedEntity, ISoftDeletable
where TKey : IEquatable
where TCreator : notnull
{
// Inherits all from IAuditedEntity plus:
// bool IsDeleted { get; set; } // From ISoftDeletable
}
```
### Composite Entities
Composite entities are designed for entities with composite primary keys.
```csharp
public interface ICompositeEntity : IConcurrency
{
// byte[]? Timestamp { get; set; } // From IConcurrency
}
public interface IAuditedCompositeEntity :
ICompositeEntity, IUserAudited
where TCreator : notnull
```
### Enumerator Entities
Enumerator entities represent lookup/reference data with additional descriptive properties.
```csharp
public interface IEnumeratorEntity : IIdentityEntity
where TKey : IEquatable
{
// Inherits from IIdentityEntity plus:
string Name { get; set; }
string? Description { get; set; }
}
```
## ⚡ Repository Pattern
### Generic Repository
The `IGenericRepository` provides standard CRUD operations, just to name a few:
```csharp
public interface IGenericRepository where TEntity : class
{
// Create operations
void Create(TEntity entity);
void Create(IEnumerable entities);
Task CreateAsync(TEntity entity, CancellationToken cancellationToken = default);
Task CreateAsync(IEnumerable entities, CancellationToken cancellationToken = default);
// Read operations
IEnumerable GetAll(bool ignoreQueryFilters = false, bool trackChanges = false);
Task> GetAllAsync(bool ignoreQueryFilters = false, bool trackChanges = false, CancellationToken token = default);
// Update operations
void Update(TEntity entity);
void Update(IEnumerable entities);
Task UpdateAsync(TEntity entity);
Task UpdateAsync(IEnumerable entities);
// Delete operations
void Delete(TEntity entity);
void Delete(IEnumerable entities);
Task DeleteAsync(TEntity entity);
Task DeleteAsync(IEnumerable entities);
// Query operations
int CountAll(bool ignoreQueryFilters = false);
Task CountAllAsync(bool ignoreQueryFilters = false, CancellationToken token = default);
}
```
### Identity Repository
Specialized repository for identity-based entities:
```csharp
public interface IIdentityRepository : IGenericRepository
where TEntity : class, IIdentityEntity
where TKey : IEquatable
{
// Strongly-typed ID operations
TEntity? GetById(TKey id);
Task GetByIdAsync(TKey id, CancellationToken cancellationToken = default);
void Delete(TKey id);
Task DeleteAsync(TKey id, CancellationToken cancellationToken = default);
}
```
## ⭐ Configuration Classes
The SQL Server package provides base configuration classes for Entity Framework Core entity type configurations.
### Identity Configuration
```csharp
public abstract class IdentityConfiguration : IEntityTypeConfiguration
where TEntity : class, IIdentityEntity
where TKey : IEquatable
{
public virtual void Configure(EntityTypeBuilder builder)
{
// Configures primary key, timestamps, and common properties
}
}
```
### Audited Configuration
```csharp
public abstract class AuditedConfiguration : IEntityTypeConfiguration
where TEntity : class, IAuditedEntity
where TKey : IEquatable
where TCreator : notnull
{
public virtual void Configure(EntityTypeBuilder builder)
{
// Configures auditing fields, required properties, and indexes
}
}
```
### Full Audited Configuration
```csharp
public abstract class FullAuditedConfiguration : IEntityTypeConfiguration
where TEntity : class, IFullAuditedEntity
where TKey : IEquatable
where TCreator : notnull
{
public virtual void Configure(EntityTypeBuilder builder)
{
// Configures full auditing including soft delete capabilities
}
}
```
## 🔮 Interceptors
The library provides Entity Framework Core interceptors for automatic handling of common scenarios.
### Time Audited Interceptor
Automatically sets `Created` and `Edited` timestamps:
```csharp
public class TimeAuditedInterceptor : SaveChangesInterceptor
{
// Automatically updates timestamps on save operations
}
```
### Soft Deletable Interceptor
Handles soft delete operations by setting `IsDeleted`:
```csharp
public class SoftDeletableInterceptor : SaveChangesInterceptor
{
// Converts hard deletes to soft deletes for applicable entities
}
```
## 💻 Getting Started
### Installation
Install the packages via NuGet Package Manager or .NET CLI:
```powershell
# For entity abstractions only
dotnet add package BB84.EntityFrameworkCore.Entities.Abstractions
# For entity implementations
dotnet add package BB84.EntityFrameworkCore.Entities
# For repository abstractions
dotnet add package BB84.EntityFrameworkCore.Repositories.Abstractions
# For repository implementations
dotnet add package BB84.EntityFrameworkCore.Repositories
# For SQL Server specific features
dotnet add package BB84.EntityFrameworkCore.Repositories.SqlServer
```
### Basic Setup
1. **Define your entities**:
```csharp
public class User : AuditedEntity
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
public class Product : FullAuditedEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public string? Description { get; set; }
}
```
2. **Create repository interfaces**:
```csharp
public interface IUserRepository : IIdentityRepository
{
Task GetByEmailAsync(string email, CancellationToken cancellationToken = default);
}
public interface IProductRepository : IIdentityRepository
{
Task> GetActiveProductsAsync(CancellationToken cancellationToken = default);
}
```
3. **Implement repositories**:
```csharp
public class UserRepository : IdentityRepository, IUserRepository
{
public UserRepository(IDbContext dbContext) : base(dbContext) { }
public async Task GetByEmailAsync(string email, CancellationToken cancellationToken = default)
{
return await GetByConditionAsync(u => u.Email == email, token: cancellationToken);
}
}
public class ProductRepository : IdentityRepository, IProductRepository
{
public ProductRepository(IDbContext dbContext) : base(dbContext) { }
public async Task> GetActiveProductsAsync(CancellationToken cancellationToken = default)
{
return await GetManyByConditionAsync(p => !p.IsDeleted, token: cancellationToken);
}
}
```
4. **Configure Entity Framework**:
```csharp
public class ApplicationDbContext : DbContext, IDbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options) { }
public DbSet Users { get; set; }
public DbSet Products { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
}
}
// Entity configurations
public class UserConfiguration : AuditedConfiguration
{
public override void Configure(EntityTypeBuilder builder)
{
builder.Property(u => u.Email).IsRequired().HasMaxLength(255);
builder.HasIndex(u => u.Email).IsUnique();
base.Configure(builder);
}
}
public class ProductConfiguration : FullAuditedConfiguration
{
public override void Configure(EntityTypeBuilder builder)
{
builder.Property(p => p.Name).IsRequired().HasMaxLength(200);
builder.Property(p => p.Price).HasPrecision(18, 2);
base.Configure(builder);
}
}
```
5. **Register services**:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options =>
options.UseSqlServer(connectionString));
services.AddScoped(provider => provider.GetService());
services.AddScoped();
services.AddScoped();
// Register interceptors
services.AddScoped();
services.AddScoped();
}
```
## 🧰 Usage Examples
### Basic CRUD Operations
```csharp
public class UserService
{
private readonly IUserRepository _userRepository;
private readonly IDbContext _dbContext;
public UserService(IUserRepository userRepository, IDbContext dbContext)
{
_userRepository = userRepository;
_dbContext = dbContext;
}
public async Task CreateUserAsync(string firstName, string lastName, string email)
{
var user = new User
{
FirstName = firstName,
LastName = lastName,
Email = email,
CreatedBy = "system" // Will be set automatically by interceptor
};
await _userRepository.CreateAsync(user);
await _dbContext.SaveChangesAsync();
return user;
}
public async Task GetUserByEmailAsync(string email)
{
return await _userRepository.GetByEmailAsync(email);
}
public async Task UpdateUserAsync(User user)
{
_userRepository.Update(user);
await _dbContext.SaveChangesAsync();
}
public async Task DeleteUserAsync(Guid userId)
{
await _userRepository.DeleteByIdAsync(userId);
await _dbContext.SaveChangesAsync();
}
}
```
### Advanced Querying
```csharp
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task> SearchProductsAsync(string searchTerm, decimal? minPrice = null)
{
return await _productRepository.GetManyByConditionAsync(p =>
!p.IsDeleted &&
p.Name.Contains(searchTerm) &&
(minPrice == null || p.Price >= minPrice));
}
}
```
## 🩺 Testing
The project includes comprehensive unit tests for all components:
### Test Projects
- **BB84.EntityFrameworkCore.Entities.Tests**: Tests for entity implementations
- **BB84.EntityFrameworkCore.Repositories.Tests**: Tests for repository implementations
### Test Coverage Areas
1. **Entity Tests**: Verify entity behavior and property assignments
2. **Repository Tests**: Test CRUD operations and query functionality
3. **Configuration Tests**: Validate Entity Framework configurations
4. **Interceptor Tests**: Test automatic auditing and soft delete behavior
### Example Test
```csharp
[TestClass]
public sealed class IdentityEntityTests
{
[TestMethod]
public void IdentityEntityTest()
{
IIdentityEntity? entity;
Guid id = Guid.NewGuid();
entity = new TestClass()
{
Id = id
};
Assert.IsNotNull(entity);
Assert.AreEqual(id, entity.Id);
Assert.IsNull(entity.Timestamp);
}
private sealed class TestClass : IdentityEntity
{ }
}
```
### Running Tests
```powershell
# Run all tests
dotnet test
# Run tests with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific test project
dotnet test tests/BB84.EntityFrameworkCore.Entities.Tests/
```
## 🛠 Build and Deployment
### Build Configuration
The project uses MSBuild properties defined in `Directory.Build.props`:
- **Target Framework**: .NET 8.0 & .NET 10.0
- **Language Version**: Latest C#
- **Nullable**: Enabled
- **Implicit Usings**: Enabled
- **Documentation**: Generated for all projects
### Version Management
Versions are automatically generated based on:
- Major: 4
- Minor: 2
- Patch: Current date (MMDD format)
- Revision: Current hour
### Package Information
- **Author**: BoBoBaSs84
- **License**: MIT
- **Repository**: https://github.com/BoBoBaSs84/BB84.EntityFrameworkCore
### Build Commands
```powershell
# Restore packages
dotnet restore
# Build solution
dotnet build
# Build release
dotnet build --configuration Release
# Pack NuGet packages
dotnet pack --configuration Release
```
### CI/CD Pipeline
The project uses GitHub Actions for:
- **Continuous Integration (CI)**: Automated building and testing
- **Continuous Deployment (CD)**: Automated package publishing
- **Code Analysis**: CodeQL security scanning
- **Dependency Updates**: Dependabot automated updates
## 📚 API Documentation
Complete API documentation is available [here](https://bobobass84.github.io/BB84.EntityFrameworkCore).
The documentation is generated using DocFX and includes:
- Complete API reference for all public types
- Code examples and usage patterns
- Cross-references between related types
- Inheritance hierarchies
### Documentation Structure
```
docs/
├── docfx.json # DocFX configuration
├── index.md # Documentation homepage
├── toc.yml # Table of contents
└── api/
└── index.md # API reference index
```
## 🤝 Contributing
### Development Guidelines
1. **Code Style**: Follow Microsoft C# coding conventions
2. **Documentation**: All public APIs must be documented with XML comments
3. **Testing**: All new features must include corresponding unit tests
4. **Breaking Changes**: Follow semantic versioning principles
### Contribution Process
1. Fork the repository
2. Create a feature branch
3. Implement changes with tests
4. Update documentation as needed
5. Submit a pull request
### Code of Conduct
This project adheres to the Contributor Covenant Code of Conduct. See the [CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) file for details.
## ⚖ License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
---