Concrete initial v3 API change proposal
@mgravell is already working on this.
Since Oct 12, 2023.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
Dapper has grown organically over time, and not all decisions were good ones. We have worked hard to try to avoid runtime or compile-time breaks, but this means we have been constrained by those poor decisions.
I would like to get to work on shipping a V2->V3 transition that fixes this, and get some breaks over and done with. As discussed here, some feature work may be shunted to the AOT project, but we need the right API for things to be effective.
What are we trying to solve?
The key problems in the API in V2 are:
- the signed/unsigned split is a nuisance - there should be one and only one Dapper if we can achieve that without breaking folks
- starting from the interfaces (
IDbConnectionetc) rather than the concrete base types (DbConnection) was a mistake CommandDefinitionwas well intentioned, but again: a mistake - we should expose cancellation via a standardCancellationTokenparameter- the shared API between buffered and unbuffered data is suboptimal (at best)
- we should add support for
DbDataSourceas a root primitive
Contraints on changes:
- where possible, we should avoid runtime breaks, and minimize compile-time breaks
Planned implementation
The first big change is: strong name the library and retire Dapper.StrongName; bad call.
My proposal for the code, effectively, is to retire the existing API but leave it in place (so: no missing methods) by removing the this modifier (so they no longer resolve as extension methods), and create a new set of extension methods - probably on a new static class that expose the preferred API, meaning: the shape we want, and the most generalized version only (no hive of forwarded methods with increasing numbers of parameters reflecting our incremental understanding of the required API). Code that is already compiled will continue unchanged using the old methods (the missing this is irrelevant and doesn't break the API). When code is recompiled, it'll resolve to the new methods.
For example:
public static class SqlMapper {
- public static IEnumerable<T> Query<T>(this IDbConnection conection, string sql, object? parameters = null, bool buffered = true, ...);
+ public static IEnumerable<T> Query<T>(IDbConnection conection, string sql, object? parameters = null, bool buffered = true, ...);
}
+ public static class DbConnectionExtensions {
+ public static List<T> Query<T>(DbConnection conection, string sql, object? parameters = null, ...);
+ public static IEnumerable<T> QueryUnbuffered<T>(DbConnection conection, string sql, object? parameters = null, ...);
+ [Obsolete("This call to AsList is no longer required")] // highlight redundant Query<T>(...).AsList() usage as a warning
+ public static List<T> AsList<T>(this List<T> source) => source;
+ }
Key changes:
- root type changes from
IDbConnectiontoDbConnection bufferedis now explicit on the method signature rather than a parameter (see the existingQueryUnbufferedAsync)asyncmethods will gainCancellationTokenparameters
However:
- all code will continue to run without recompile (ignoring the signed/unsigned fun)
- most code will require zero changes to compile (unless they are explicitly specifying buffered, in which case either a: remove
buffered: false, or b: switch toQueryUnbuffered) - the change to return
List<T>in the default buffered case makes reality explicit; in theory this could change how calling code operates, but this is considered to be a positive thing - for example,foreachwill be more efficient if it knows it is starting fromList<T>due to duck-typing
We'll need to list out the full proposal set, but before we get too far: I want to gather feedback on the overall shape of this suggestion.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.