diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 545c966..caa266a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -5,52 +5,43 @@ on:
release:
types:
- published
-
+
env:
# Stop wasting time caching packages
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
# Disable sending usage data to Microsoft
DOTNET_CLI_TELEMETRY_OPTOUT: true
# GitHub Packages Feed settings
- GITHUB_FEED: https://nuget.pkg.github.com/koenbeuk/
- GITHUB_USER: koenbeuk
+ GITHUB_FEED: https://nuget.pkg.github.com/autoguru-au/
+ GITHUB_USER: autoguru-au
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
+
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
- version: [1, 2, 3]
- include:
- - version: 1
- configuration: ReleaseV1
- - version: 2
- configuration: ReleaseV2
- - version: 3
- configuration: Release
- runs-on: ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Setup .NET Core
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- include-prerelease: True
- name: Install dependencies
- run: dotnet restore EntityFrameworkCore.Triggered.sln -p:Configuration=${{ matrix.configuration }}
+ run: dotnet restore EntityFrameworkCore.Triggered.sln -p:Configuration=Release
- name: Build
- run: dotnet build --configuration ${{ matrix.configuration }} --no-restore EntityFrameworkCore.Triggered.sln
+ run: dotnet build --configuration Release --no-restore EntityFrameworkCore.Triggered.sln
- name: Test
- run: dotnet test --configuration ${{ matrix.configuration }} --verbosity normal EntityFrameworkCore.Triggered.sln
+ run: dotnet test --configuration Release --verbosity normal EntityFrameworkCore.Triggered.sln
- name: Pack
if: matrix.os == 'ubuntu-latest'
- run: |
- dotnet pack -v normal --configuration ${{ matrix.configuration }} --include-symbols --include-source -p:PackageVersion=${{ matrix.version }}-pre-$GITHUB_RUN_ID -o nupkg EntityFrameworkCore.Triggered.Core.slnf
+ run: |
+ dotnet pack -v normal --configuration Release --include-symbols --include-source -p:PackageVersion=3-pre-$GITHUB_RUN_ID -o nupkg EntityFrameworkCore.Triggered.Core.slnf
- name: Upload Artifact
if: matrix.os == 'ubuntu-latest'
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: nupkg
path: ./nupkg/*.nupkg
@@ -59,27 +50,26 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
- runs-on: ${{ matrix.os }}
-
+ runs-on: ${{ matrix.os }}
+
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Setup .NET Core
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- include-prerelease: True
- name: Install dependencies
run: dotnet restore EntityFrameworkCore.Triggered.Samples.slnf
- name: Build
- run: dotnet build --configuration Release --no-restore EntityFrameworkCore.Triggered.Samples.slnf
-
+ run: dotnet build --configuration Release --no-restore EntityFrameworkCore.Triggered.Samples.slnf
+
prerelease:
needs: build
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
steps:
- name: Download Artifact
- uses: actions/download-artifact@v1
+ uses: actions/download-artifact@v4
with:
name: nupkg
- name: Push to GitHub Feed
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 3bde8a6..969ebd3 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -3,27 +3,27 @@ on:
release:
types:
- published
-
+
env:
# Stop wasting time caching packages
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
# Disable sending usage data to Microsoft
DOTNET_CLI_TELEMETRY_OPTOUT: true
# GitHub Packages Feed settings
- GITHUB_FEED: https://nuget.pkg.github.com/koenbeuk/
- GITHUB_USER: koenbeuk
+ GITHUB_FEED: https://nuget.pkg.github.com/autoguru-au/
+ GITHUB_USER: autoguru-au
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Official NuGet Feed settings
NUGET_FEED: https://api.nuget.org/v3/index.json
NUGET_KEY: ${{ secrets.NUGET_KEY }}
-
+
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Setup .NET Core
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Create Release NuGet package
@@ -31,12 +31,9 @@ jobs:
arrTag=(${GITHUB_REF//\// })
VERSION="${arrTag[2]}"
echo Version: $VERSION
- CONFIGURATION=$([ "${VERSION:0:2}" == "v1" ] && echo "ReleaseV1" || echo "Release")
- CONFIGURATION=$([ "${VERSION:0:2}" == "v2" ] && echo "ReleaseV2" || echo $CONFIGURATION)
VERSION="${VERSION:1}"
echo Clean Version: $VERSION
- echo Configuration: $CONFIGURATION
- dotnet pack -v normal -c $CONFIGURATION --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg EntityFrameworkCore.Triggered.Core.slnf
+ dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg EntityFrameworkCore.Triggered.Core.slnf
- name: Push to GitHub Feed
run: |
for f in ./nupkg/*.nupkg
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..cf329de
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,78 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Project Overview
+
+EntityFrameworkCore.Triggered is a library that adds trigger support to EF Core. Triggers respond to entity changes before and after they are committed to the database, similar to SQL database triggers but implemented in C#.
+
+## Build Commands
+
+```bash
+# Build (v3 is the default configuration on this branch)
+dotnet build EntityFrameworkCore.Triggered.sln
+
+# Run all tests
+dotnet test EntityFrameworkCore.Triggered.sln
+
+# Run a single test project
+dotnet test test/EntityFrameworkCore.Triggered.Tests
+
+# Run a specific test by filter
+dotnet test test/EntityFrameworkCore.Triggered.Tests --filter "FullyQualifiedName~TriggerSessionTests"
+
+# Build only core libraries (no samples)
+dotnet build EntityFrameworkCore.Triggered.Core.slnf
+
+# Build samples only
+dotnet build EntityFrameworkCore.Triggered.Samples.slnf
+```
+
+## Multi-Version Build System
+
+The repo supports 3 major versions via `$(EFCoreTriggeredVersion)` in `Directory.Build.props`:
+- **V1**: EF Core 3.1, `netstandard2.0`, config `ReleaseV1`/`DebugV1`
+- **V2**: EF Core 5.0, `netstandard2.1`, config `ReleaseV2`/`DebugV2`
+- **V3** (current branch): EF Core 6.0+, `net6.0`, config `Release`/`Debug`
+
+Source files use `#if` directives with `EFCORETRIGGERED_V1`, `EFCORETRIGGERED_V2`, `EFCORETRIGGERED_V3` for version-specific code.
+
+## Build Settings
+
+- `TreatWarningsAsErrors` is enabled globally
+- Nullable reference types are enabled globally (`enable`)
+- Language version is C# 9.0
+- Strong-name signing is used (`EntityFrameworkCore.Triggered.snk`)
+
+## Architecture
+
+### NuGet Packages (src/)
+
+- **Abstractions** — Trigger interfaces only (`IBeforeSaveTrigger`, `IAfterSaveTrigger`, `IAfterSaveFailedTrigger`, `ITriggerContext`, lifecycle triggers)
+- **EntityFrameworkCore.Triggered** — Core implementation: trigger session management, SaveChanges interception, cascading support
+- **Extensions** — Assembly scanning for auto-discovery of triggers via `AddAssemblyTriggers()`
+- **Transactions** / **Transactions.Abstractions** — Transaction-scoped triggers (`IBeforeCommitTrigger`, `IAfterCommitTrigger`, etc.)
+
+### Core Flow
+
+1. **Registration**: Triggers are registered via `options.UseTriggers(t => t.AddTrigger())` on `DbContextOptionsBuilder`
+2. **Interception**: `TriggerSessionSaveChangesInterceptor` hooks into EF Core's `SaveChanges`/`SaveChangesAsync`
+3. **Execution order**: BeforeSaveStarting → BeforeSave (with cascading) → CaptureChanges → BeforeSaveCompleted → [actual SaveChanges] → AfterSaveStarting → AfterSave → AfterSaveCompleted
+4. **Cascading**: BeforeSave triggers can modify entities, causing additional trigger invocations. Controlled by `ICascadeStrategy` with a configurable max cycle count (default 100).
+
+### Key Internal Types
+
+- `TriggerSession` (`TriggerSession.cs`) — Orchestrates trigger execution for a single SaveChanges call
+- `TriggerService` (`TriggerService.cs`) — Factory for trigger sessions, manages current session state
+- `TriggerSessionSaveChangesInterceptor` (`Internal/`) — EF Core `ISaveChangesInterceptor` implementation
+- `TriggersOptionExtension` (`Infrastructure/Internal/`) — EF Core options extension that registers all trigger services
+- `TriggerContextTracker` — Wraps EF Core's ChangeTracker to produce `TriggerContext` instances
+
+### Test Projects (test/)
+
+- **Tests** — Unit tests for the core library (xUnit + ScenarioTests.XUnit)
+- **Extensions.Tests** — Tests for assembly scanning
+- **IntegrationTests** — End-to-end tests
+- **Transactions.Tests** — Transaction trigger tests
+
+Tests use EF Core InMemory and SQLite providers.
diff --git a/Directory.Build.props b/Directory.Build.props
index 7df2156..200d4c1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,10 +11,10 @@
Triggers for EF Core. Respond to changes in your ApplicationDbContext before and after they are committed to the database
Git
- https://github.com/koenbeuk/EntityFrameworkCore.Triggered
- Koen Bekkenutte
+ https://github.com/autoguru-au/EntityFrameworkCore.Triggered
+ AutoGuru
EntityFramework;EFCore;Triggers;SQLServer;SqlLite;CosmosDb;.NET Core;aspnetcore
- https://github.com/koenbeuk/EntityFrameworkCore.Triggered
+ https://github.com/autoguru-au/EntityFrameworkCore.Triggered
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 06d4f16..d059cad 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -17,6 +17,7 @@
+ AutoGuru.$(MSBuildProjectName)
true
true
snupkg