M3: Dapper coexistence proof (closes Phase 1)#3
Merged
Conversation
M3 introduces the first integration test project, needing a real
dependency (a database provider) rather than hand-rolled fakes. Adds
test/<ProjectName>.IntegrationTests/ alongside .UnitTests/ in
architecture.md, and broadens Directory.Build.props' test-project
condition from EndsWith('.UnitTests') to EndsWith('Tests') so the
XML-doc exemption and IsPackable=false apply to it too, without
needing another edit for the next test-suffixed project.
The first integration test project, referencing SqlBound, Dapper, and Microsoft.Data.Sqlite so the coexistence proof can run against a real ADO.NET provider instead of the hand-rolled fakes used in the unit tests. SQLite over SQL Server here: the coexistence proof only depends on the shared ADO.NET abstraction, not on any SQL-Server-specific behavior (that's M7's job), and SQLite needs no external service or CI setup. Pins SQLitePCLRaw.lib.e_sqlite3 to 3.53.3 directly: Microsoft.Data.Sqlite 10.0.9 transitively pulls 2.1.11, which carries a known high-severity vulnerability (CVE-2025-6965, a SQLite memory-corruption issue fixed upstream in SQLite 3.50.2) that NuGet's audit now fails restore on.
Three scenarios against a real SQLite provider, each opening its own isolated in-memory connection: - interleaving SqlSession and Dapper calls on the same open connection - a transaction shared between both libraries: commit persists both libraries' writes - the same shared transaction: rollback discards both libraries' writes The rollback case is the strongest proof of genuine sharing — if either library weren't truly enlisted in the same transaction, its write would survive the rollback. Both namespaces (Dapper, SqlBound) are imported in the same file with zero method-name ambiguity, proven by compiling rather than by a runtime assertion, since SqlBound deliberately never defines Query*/Execute*/ExecuteScalar* extensions on DbConnection. All three passed on the first run against the real provider — SqlSession was previously verified only against hand-rolled fakes (M2), and this is the first confirmation its parameter binding and transaction handling work correctly against a live ADO.NET provider, not just idealized fake behavior. This project (and these tests) stay in the suite permanently so a coexistence regression fails CI.
Bumps PackageVersion from 0.1.0-preview.1 to the clean 0.1.0 so the v0.1.0 tag applied to this commit after merge matches the version it actually marks — a tag should name the exact package a revision produces. Dropping the suffix doesn't overclaim stability: every 0.x version is already "anything may change" under semver, so 0.1.0 promises no more than 0.1.0-preview.1 did. Records the convention in workflow.md: PackageVersion carries a prerelease suffix during a phase's active development, and closing the phase drops it in the same commit that gets tagged. The next phase's first commit starts the new prerelease line.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Milestone 3 (Phase 1 — Bedrock, final milestone) of the SqlBound roadmap: proof that Dapper and SqlBound genuinely coexist — same connection, same transaction, both namespaces imported, zero ambiguity — as a permanent automated test rather than a one-off demo.
SqlBound.IntegrationTests: the first integration test project, referencingDapperandMicrosoft.Data.SqlitealongsideSqlBound. SQLite over SQL Server here — the coexistence proof only depends on the shared ADO.NET abstraction, not on SQL-Server-specific behavior (that's M7's job), and SQLite needs no external service or CI setup.DapperCoexistenceTests: three scenarios, each against a real (isolated, in-memory) SQLite connection:SqlSessionand Dapper calls on the same open connection.DbTransactionshared between both libraries: commit persists both libraries' writes.using Dapper;and (implicitly, via enclosing namespace) SqlBound's types together — not a runtime assertion — since SqlBound deliberately never definesQuery*/Execute*/ExecuteScalar*extensions onDbConnection.All three passed on the first run against the real provider.
SqlSessionhad previously only been verified against M2's hand-rolled ADO.NET fakes; this is the first confirmation its parameter binding and transaction handling work correctly against a live provider, not just idealized fake behavior.Governance: documented the
test/<ProjectName>.IntegrationTests/convention inarchitecture.md, alongside the existing.UnitTests/one.Phase 1 close-out:
PackageVersiondrops its-preview.1suffix to the clean0.1.0, so thev0.1.0tag (to be applied after this merges) names the exact package this revision produces. Convention recorded inworkflow.md: prerelease during a phase's active development, clean version on the commit that gets tagged, new prerelease line starts the next phase.Why
This is the empirical test of the project's core value proposition — a compile-time-verified SQL library that developers can adopt incrementally without displacing Dapper. Closing Phase 1 here also means the roadmap's Bedrock phase (skeleton, execution core, coexistence) is complete before any codegen work begins in Phase 2.
Reviewer notes
Microsoft.Data.Sqlitesurfaced that it transitively pullsSQLitePCLRaw.lib.e_sqlite32.1.11, which has a known high-severity vulnerability (CVE-2025-6965, a SQLite memory-corruption bug fixed upstream in SQLite 3.50.2) that NuGet's audit blocks restore on by default. Pinned directly to 3.53.3 intest/SqlBound.IntegrationTests/SqlBound.IntegrationTests.csproj.Directory.Build.props's test-project condition broadened fromEndsWith('.UnitTests')toEndsWith('Tests')so the XML-doc exemption andIsPackable=falseapply to.IntegrationTeststoo.Microsoft.Data.Sqliterestores its native binaries forubuntu-latestautomatically, anddotnet testalready runs at the solution level.masterasv0.1.0and pushing the tag, per the workflow rules — will do that separately with explicit confirmation once this is merged.Test plan
dotnet build(0 warnings),dotnet format --verify-no-changes(clean),dotnet test(31 unit + 3 integration, all passing),dotnet pack(producesSqlBound.0.1.0.nupkg)🤖 Generated with Claude Code