RepoDB
RepoDB copied to clipboard
Request: [MAJOR] Refactor the RepoDB library into multiple Nuget Packages (Consideration to v2.0?)
The intention is to only segregate the DOMAIN from the IMPLEMENTATIONS to simplify the extensibilities. All the existing objects and namespaces will not be affected even if they are moved to the new packages. There should be no code changes on the consumer side.
Describe the request
As the library is growing bigger and slowly becoming more complex than it was, it was likely (or better) to have the objects separated into multiple Nuget packages.
Basically, the UNION architecture is a better option on this scenario, in which, the DOMAIN and the IMPLEMENTATIONS are separated into multiple packages and simplify the reusability of the components.
Think of this, the library is most likely consisting the following segregations in terms of features and capabilities.
- Core/Basic/Domain
- Operations
- Specializations (Tracing/Logging, Caching, Event Handling, etc)
- Extensions
Describe your wish
As we see it, there should be the following Nuget Packages.
- RepoDb.Domain
- RepoDb.Domain.<Cache|Trace|Operations|Specializations|Extensions>
- RepoDb (better if RepoDb.Core) - (THE MAIN PACKAGE)
- RepoDb.Operations
- RepoDb.SqlServer
- RepoDb.SqlServer.BulkOperations
- RepoDb.PostgreSql
- RepoDb.PostgreSql.BulkOperations
- RepoDb.MySql
- RepoDb.MySqlConnector
- RepoDb.Sqlite.Microsoft
- RepoDb.SQLite.System
- RepoDb.Extensions
- RepoDb.Extensions.<SqlServer|PostgreSql|MySql|MySqlConnector|Sqlite|SQLite>
So, considering the following scenarios, you most likely have to only install the following to maintain the lightweight(ness) of the application.
Only if RawSQL (Execute Methods)
- RepoDb.Domain
- RepoDb
Only if Operations (Query, Insert, Merge, Update, Delete)
- RepoDb.Domain
- RepoDb
- RepoDb.Operations
If with Tracing
- RepoDb.Trace
If with Caching
- RepoDb.Caching
If with Specific DB Providers
- RepoDb.SqlServer or RepoDb.<PostgreSql/MySql/MySqlConnector/Sqlite/SQLite>
If with SQL Server BulkOperations
- RepoDb.SqlServer.BulkOperations
And many more.
Rationale
With these, we are not required anymore to install everything at once and can always extend the library targeting the objects residing on the RepoDb.Domain or RepoDb.Domain.* package.
Example: The newly created Query Field objects under the namespace (RepoDb.Extensions.QueryFields). Theses object are best if being placed on the new package named RepoDb.Extensions, however, the implementation is not ideal as they directly inherits the QueryField object from the RepoDb main package, in which architecturally should reside on the RepoDb.Domain.
Creating a new extension package that references the core package is not advisable as it enable the developers to just install the extension and everything would like like a charm (which is truly a big mistake).
And, there a lot more of scenarios.
Advantages
Simplicity on the maintenance and extensibilities in all areas. This is given with UNION architecture or the similar.
The application is only referencing the required libraries to run the needed feature and capabilities, with this, the application is more lightweight as it should.
Note: Though, in general, the RepoDb library is still very lightweight.
Drawback
Complexity on referencing the different features and capabilities. If you required the full features, you may ended-up referencing too many Nuget packages.
Practically, as the library author, I have a feeling (instinct) that this may annoyed the users at some point as it sound not too practical to separate the capabilities/functionalities into multiple packages if you are using an OSS library like an ORM.
RepoDB packages are really lightweight and I understand the maintainability and extensibility aspects, but from the user perspective the current set-up (RepoDB, one package per DBMS, one for bulk operations) is a good compromise. I think that introducing so many packages could complicate things a lot for someone who just need to "use" RepoDB, so much granularity might be unnecessary for the users..
Agreed, the potential "overhead" of unused functionality in the main library is not that important. The administrative overhead of having to install and multiple packages up to date is way more important. Especially since almost every project that goes this direction seems to end up with multiple packages all having the same "synchronized" version numbers and dependencies.
Please stick with one main package, and only keep database specific implementations separate when they require extra dependencies. I would even prefer having MSSQL, MySQL, Postgres, etc support all in the main library as long as it doesn't add more external dependencies.
This is not (at least to me) a frontend library where every kilobyte counts. On backend, I rather have one bigger package to keep up to date, than having to track multiple dependencies for the same feature.
@w5l - thanks for sharing your thoughts. I seconding the fact that maintaining the versions of different packages are frustrating than having the "overhead of unused feature on a single package". And besides, this is a big breaking changes to the community so if we are to do this, this will require a very deep collaboration and interaction with the users itself. As of writing this, we refrain on doing this.
@mikependon Could you please elaborate on this ?
"Creating a new extension package that references the core package is not advisable as it enable the developers to just install the extension and everything would like like a charm (which is truly a big mistake)."
And I agree with all, it's more cumbersome than anything else really.
I think, in general, there is a package design problem with RepoDB. The perfect ONION architecture could be like below.
// Base
RepoDb.Core.dll - in which it should contains the following > RepoDb.ITrace.cs > RepoDb.ICache.cs > RepoDb.IStatementBuilder.cs > And all other base classes
// Core
RepoDb.Raw.dll > RepoDb.Core.dll > Some DB Connection raw functionalities (i.e: ExecuteQuery, ExecuteNonQuery, ExecuteScalar)
// Fluent
RepoDb.Fluent.dll > RepoDb.Core.dll > Some DB Connection fluent functionalities (i.e: Insert, Update, Delete, etc)
// Trace
RepoDb.Trace.dll > RepoDb.Core.dll
// Cache
RepoDb.Cache.dll > RepoDb.Core.dll
But, it sounds like it is impossible to implement on the current design as making like below, would completely oppose the design above (implementation-wise), unless we rewrote most of it.
// Trace
RepoDb.Trace.dll > RepoDb.ITrace.cs
RepoDb.Cache.dll > RepoDb.ICache.cs
RepoDb.Core.dll > RepoDb.Trace.dll (installable via Nuget as per needed) > RepoDb.Cache.dll (installable via Nuget as per needed)
For me, it is just not advisable to re-implement most of it as they are now stable just to support this decoupling. So we need to balance it.