{"id":28747973,"url":"https://github.com/gravity00/dapprwire","last_synced_at":"2026-02-16T12:27:48.276Z","repository":{"id":295996366,"uuid":"990960033","full_name":"gravity00/DapprWire","owner":"gravity00","description":"Lightweight library for seamless Dapper integration with Microsoft DI (or any other DI container)","archived":false,"fork":false,"pushed_at":"2025-06-16T10:47:28.000Z","size":2522,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-16T10:49:46.480Z","etag":null,"topics":["csharp","dapper","database","dotnet","dotnet-core","sql"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gravity00.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T23:13:49.000Z","updated_at":"2025-06-16T10:47:32.000Z","dependencies_parsed_at":"2025-05-28T13:35:47.181Z","dependency_job_id":"d40a82c3-b263-4cbf-b423-d948e25582fb","html_url":"https://github.com/gravity00/DapprWire","commit_stats":null,"previous_names":["gravity00/dapperwire","gravity00/dapprwire"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gravity00/DapprWire","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity00%2FDapprWire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity00%2FDapprWire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity00%2FDapprWire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity00%2FDapprWire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gravity00","download_url":"https://codeload.github.com/gravity00/DapprWire/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity00%2FDapprWire/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260205147,"owners_count":22974290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dapper","database","dotnet","dotnet-core","sql"],"created_at":"2025-06-16T17:37:41.085Z","updated_at":"2026-01-08T13:19:08.823Z","avatar_url":"https://github.com/gravity00.png","language":"C#","readme":"# :pushpin: DapprWire - Dapper + Microsoft DI made easy\n\n**DapprWire** simplifies the integration of **Dapper** into **Microsoft's Dependency Injection (DI) container**, making database connectivity effortless and efficient. It provides an abstraction layer for **connection and transaction management**, that can be easily injected into your services or repositories, while exposing all Dapper operations so you can use it as your micro-ORM the same way you use **Dapper**.\n\nIf you're tired of manually wiring `IDbConnection` into Microsoft DI, reminding yourself to pass `IDbTransaction` as an argument, or simply have some logs to help analyzing production problems, **DapprWire** provides a clean and simple solution for that.\n\n## :briefcase: Packages\n\n| Package | NuGet | Downloads |\n| ------- | ----- | --------- |\n| [DapprWire.Contracts](https://www.nuget.org/packages/DapprWire.Contracts) | [![DapprWire.Contracts](https://img.shields.io/nuget/v/DapprWire.Contracts.svg)](https://www.nuget.org/packages/DapprWire.Contracts) | [![DapprWire.Contracts](https://img.shields.io/nuget/dt/DapprWire.Contracts.svg)](https://www.nuget.org/packages/DapprWire.Contracts) |\n| [DapprWire](https://www.nuget.org/packages/DapprWire) | [![DapprWire](https://img.shields.io/nuget/v/DapprWire.svg)](https://www.nuget.org/packages/DapprWire) | [![DapprWire](https://img.shields.io/nuget/dt/DapprWire.svg)](https://www.nuget.org/packages/DapprWire) |\n| [DapprWire.MicrosoftExtensions](https://www.nuget.org/packages/DapprWire.MicrosoftExtensions) | [![DapprWire.MicrosoftExtensions](https://img.shields.io/nuget/v/DapprWire.MicrosoftExtensions.svg)](https://www.nuget.org/packages/DapprWire.MicrosoftExtensions) | [![DapprWire.MicrosoftExtensions](https://img.shields.io/nuget/dt/DapprWire.MicrosoftExtensions.svg)](https://www.nuget.org/packages/DapprWire.MicrosoftExtensions) |\n\nPackage Purposes:\n\n* **DapprWire.Contracts** - library that only contains contracts like `IDatabase`, `IDatabaseSession`, `IDatabaseTransaction` or `SqlOptions`, usefull if you want to decouple from implementation details; \n* **DapprWire** - library with core implementations like `Database`, `DatabaseSession` or `DatabaseTransaction`;\n* **DapprWire.MicrosoftExtensions** - extension library for `Microsoft.Extension.*` packages that helps with container registration or logging SQL statements into `ILogger` instances;\n\n### Compatibility\n\nAll packages directly target the following frameworks:\n\n* .NET Framework 4.6.1;\n* .NET Standard 2.0;\n* .NET Standard 2.1;\n* .NET 5.0\n* .NET 8.0\n* .NET 10.0\n\nThis means you should be able to use it almost everywhere that needs to access a SQL database, from an ASP.NET Core 8 application to a Windows Service, command line terminal and even on older ASP.NET Core 2 applications.\n\n## :rocket: Features\n\nBy managing database connections and transactions for you, **DapprWire** simplifies how you use **Dapper**. Here are some of the top features that you can read in more detail on the [Wiki documentation](https://github.com/gravity00/DapprWire/wiki):\n\n### :white_check_mark: Automatic Dependency Injection Registration\n\nIf your application uses `Microsoft.Extensions.DependencyInjection`, simply install the `DapprWire.MicrosoftExtensions` package:\n\n```sh\ndotnet add package DapprWire.MicrosoftExtensions\n```\n\nThen use the extension method `AddDatabase` to register the required services into the container - you only need to provide a function that creates the `DbConnection` using any database driver you may prefer:\n\n```cs\nvar connectionString = builder.Configuration.GetConnectionString(\"ProductsDatabase\");\nbuilder.Services.AddDatabase(_ =\u003e new Microsoft.Data.SqlClient.SqlConnection(connectionString));\n```\n\nInstead of using `DbConnection` directly, you can now inject instances of `IDatabaseSession`, which offer the same methods as Dapper but behave like a unit of work, with a **scoped lifetime**.\nIf you need to manage directly the lifetime of a `IDatabaseSession`, you can instead inject the `IDatabase` **singleton** and create as many database sessions as you need.\n\n```cs\n[Route(\"products\")]\npublic class ProductsController(IDatabaseSession databaseSession) : ControllerBase\n{\n  [HttpGet]\n  public async Task\u003cIEnumerable\u003cProductModel\u003e GetAllAsync(CancellationToken ct)\n  {\n    return await databaseSession.QueryAsync\u003cProductModel\u003e(\n      \"select Id, Code, Name from Products\",\n      ct\n    );\n  }\n}\n```\n\n### :white_check_mark: Multiple Database Support\n\nIf your application needs to connect to multiple databases, like a service that synchronizes data between multiple systems, you can easily define multiple `IDatabaseName`, one for each database you need to connect.\n\n```cs\npublic sealed class ProductsDatabase : IDatabaseName;\n\npublic sealed class ClientsDatabase : IDatabaseName;\n```\n\nThen use the `AddDatabase\u003cTName\u003e` or, if you want one of the databases to be the fallback when no name is specified, `AddDatabaseAsDefault\u003cTName\u003e` methods to register the required services, while providing a `DbConnection` factory for each:\n\n```cs\nvar productsDatabaseConnectionString = builder.Configuration.GetConnectionString(\"ProductsDatabase\");\nbuilder.Services.AddDatabaseAsDefault\u003cProductsDatabase\u003e(\n  _ =\u003e new Microsoft.Data.SqlClient.SqlConnection(productsDatabaseConnectionString)\n);\n\nvar clientsDatabaseConnectionString = builder.Configuration.GetConnectionString(\"ClientsDatabase\");\nbuilder.Services.AddDatabase\u003cClientsDatabase\u003e(\n  _ =\u003e new Oracle.ManagedDataAccess.Client.OracleConnection(clientsDatabaseConnectionString)\n);\n```\n\nYou can now inject generic instances of `IDatabaseSession\u003cTName\u003e` or `IDatabase\u003cTName\u003e` into your services or repositories and use them like you would with a single database.\n\n```cs\n[Route(\"products\")]\npublic class ProductsController(\n  IDatabaseSession\u003cProductsDatabase\u003e productsDatabaseSession,\n  IDatabaseSession\u003cClientsDatabase\u003e clientsDatabaseSession,\n  IDatabaseSession databaseSession // 'ProductsDatabase' was defined as default, so this is the same instance as 'productsDatabaseSession'\n) : ControllerBase\n{\n  // ...\n}\n```\n\n### :white_check_mark: Database Transactions\n\nWhen you need to manage database transactions, after starting a new transaction **DapprWire** will automatically pass it to **Dapper** when executing any database operation until it is disposed, preventing transactional problems:\n\n```cs\nawait using var tx = await databaseSession.BeginTransactionAsync(ct);\n\nvar productId = await databaseSession.ExecuteScalarAsync\u003clong\u003e(\n  \"insert into Products(Code, Name) values (@Code, @Name);select cast(SCOPE_IDENTITY() as bigint);\",\n  new\n  {\n    Code = \"12345\",\n    Name = \"Product 12345\"\n  },\n  ct\n);\n\nawait databaseSession.ExecuteAsync(\n  \"insert into Events(Description) values (@Description)\",\n  new\n  {\n    Description = $\"Product {productId} was created!\"\n  },\n  ct\n);\n\nawait tx.CommitAsync(ct);\n```\n\nKeep in mind that, when using multiple databases, **DapprWire** only manages the transaction for each session individually so you need so solve distributed transaction problems on your own.\n\n### :white_check_mark: Asynchronously Stream Large Result Sets\n\nWhen dealing with large result sets, loading everything into memory at once may not be the best approach.\n**DapprWire** has built-in support for `IAsyncEnumerable\u003cT\u003e` so you can stream and map results directly from the database without loading everything into memory first:\n\n```cs\nvar productsStream = databaseSession.QueryStreamed\u003cProductModel\u003e(\n  \"select Id, Code, Name from Products\",\n  ct\n);\nawait foreach (var product in productsStream)\n{\n  // Process each product as it is received from the database\n}\n```\n\n### :white_check_mark: Logging and Default Options\n\n**DapprWire** has native support for logging, which means that everytime you open a new database session, transaction or execute an SQL command it will be logged, if enabled.\nBy default, logging is disabled except when using the `DapprWire.MicrosoftExtensions` package since it will use Microsoft `ILogger` façade so you can manage logging configurations via application settings.\n\n```sh\n2025-06-09T14:40:41.3136668+00:00 [Debug] DapprWire.Database | Starting a new database session...\n2025-06-09T14:40:41.3137026+00:00 [Debug] DapprWire.DatabaseSession | Creating a new database connection...\n2025-06-09T14:40:41.3138825+00:00 [Debug] DapprWire.DatabaseSession | Opening the database connection...\n2025-06-09T14:40:41.3139286+00:00 [Info] DapprWire.DatabaseSession | Database connection opened successfully.\n2025-06-09T14:40:41.3139347+00:00 [Info] DapprWire.Database | Database session started successfully.\n2025-06-09T14:40:41.3140091+00:00 [Debug] DapprWire.DatabaseSession | Starting a new database transaction [IsolationLevel:ReadCommitted]\n2025-06-09T14:40:41.3157917+00:00 [Info] DapprWire.DatabaseSession | Database transaction started successfully\n2025-06-09T14:40:41.3158548+00:00 [Debug] DapprWire.DatabaseSession | Executing SQL command\n[HasParameters:True IsTransactional:True Timeout:\u003cnull\u003e Type:\u003cnull\u003e]\ninsert into Products(Code, Name) values (@Code, @Name);select cast(SCOPE_IDENTITY() as bigint);\n2025-06-09T14:40:41.3168732+00:00 [Debug] DapprWire.DatabaseSession | Executing SQL command\n[HasParameters:True IsTransactional:True Timeout:\u003cnull\u003e Type:\u003cnull\u003e]\ninsert into Events(Description) values (@Description)\n2025-06-09T14:40:41.3180452+00:00 [Debug] DapprWire.DatabaseTransaction | Committing the database transaction...\n2025-06-09T14:40:41.3239587+00:00 [Info] DapprWire.DatabaseTransaction | Database transaction committed successfully.\n```\n\nYou can assign your own `DatabaseLogger` and other options, like default command timeout, transaction isolation level and even a callback when a new `DbConnection` is open by configuring the available `DatabaseOptions`.\nWhen using `DapprWire.MicrosoftExtensions` package you can either configure just like any other `IOptions` using `Configure\u003cDatabaseOptions\u003e(...)` method or pass a configuration callback to the `AddDatabase` methods:\n\n```cs\nvar connectionString = builder.Configuration.GetConnectionString(\"ProductsDatabase\");\nbuilder.Services.AddDatabase(_ =\u003e new SqlConnection(connectionString), options =\u003e\n{\n  options.Logger = DatabaseLogger.Null;\n  options.DefaultTimeout = 5;\n  options.DefaultIsolationLevel = IsolationLevel.ReadCommitted;\n});\n```\n\n## :hammer: Build\n\nYou should be able to easily build this solution as long you have installed both SDKs for .NET 8.0 and .NET Framework 4.8, but more recent versions should also work.\n\n```sh\ngit clone https://github.com/gravity00/DapprWire.git DapprWire\ncd .\\DapprWire\ndotnet build\n```\n\n## :construction: Test\n\nThis library is focused on interacting with SQL databases and unit tests currently require a running SQL Server instance.\nTo make the setup easier, the library [Testcontainers](https://testcontainers.com/) is used so you only need Docker running on your local machine and everything should run as expected.\n\n```sh\ngit clone https://github.com/gravity00/DapprWire.git DapprWire\ncd .\\DapprWire\ndotnet test\n```\n\nKeep in mind the first execution may take some time because images may need to be automatically downloaded first.\n\nIf you prefer to use another database, either using Testcontainers or not, simply open the [DatabaseFixture.cs](https://github.com/gravity00/DapprWire/blob/main/test/DapprWire.Tests/DatabaseFixture.cs) file and change to your needs.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgravity00%2Fdapprwire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgravity00%2Fdapprwire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgravity00%2Fdapprwire/lists"}