Code29.Pomade
1.1.0
dotnet add package Code29.Pomade --version 1.1.0
NuGet\Install-Package Code29.Pomade -Version 1.1.0
<PackageReference Include="Code29.Pomade" Version="1.1.0" />
<PackageVersion Include="Code29.Pomade" Version="1.1.0" />
<PackageReference Include="Code29.Pomade" />
paket add Code29.Pomade --version 1.1.0
#r "nuget: Code29.Pomade, 1.1.0"
#:package Code29.Pomade@1.1.0
#addin nuget:?package=Code29.Pomade&version=1.1.0
#tool nuget:?package=Code29.Pomade&version=1.1.0
Pomade - making (async) Dapper code testable
This project is a fork of the Pomade project by Matt Oswald (moswald) with updated Dapper dependencies for .Net 10. All credit to him for his prior work. The original project is here and the NuGet page is here. The only changes made are updates to dependencies, comments and formatting.
About
Dapper is a great "mini ORM" library, but it's implemented almost entirely with extension methods which makes calling code very difficult to test. Pomade helps by forwarding calls to Dapper through virtual methods.
Also it helps by only implementing the async methods. *cough* 😇
Explanation
Dapper extends the IDbConnection interface with methods like QueryAsync:
IDbConnection _connection = new SqlConnection();
public Task<Dog> LookupDog(Guid guid)
=> _connection.QueryAsync<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
Unfortunately, this makes LookupDog() difficult to test as _connection is not easily replaced by most mocking frameworks.
Pomade helps get around this limitation by instead making those extension methods virtual members, and thus, mockable. To use, pass your IDbConnection reference to the Pomade class constructor and use that as your data access layer:
Pomade _connection = new Pomade(new SqlConnection());
public Task<Dog> LookupDog(Guid guid)
=> _connection.QueryAsync<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
Other than the type of the _connection field, the important stuff is exactly the same. The real difference comes in your tests. Since Pomade.QueryAsync<T> is a virtual method, you can inject Pomade instances into your tests and once again enjoy the ability to easily mock the database layer away.
Test example using NSubstitute:
var db = Substitute.ForPartsOf<Pomade>();
db.QueryAsync<Dog>(Arg.Any<string>(), Arg.Any<object>())
.Returns(new Dog("Fido"));
Performance
"Dapper is stupid fast, aren't you just slowing it down by making all the calls virtual?"
Nope.
| Method | Mean | Error | StdDev | Scaled |
|---|---|---|---|---|
| Dapper | 216.1 us | 0.7570 us | 0.5910 us | 1.00 |
| Pomade | 216.6 us | 1.8440 us | 1.5398 us | 1.00 |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Dapper (>= 2.1.79)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0 | 41 | 9/10/2026 |