RepoDB icon indicating copy to clipboard operation
RepoDB copied to clipboard

Request: [MAJOR] Refactor the RepoDB library into multiple Nuget Packages (Consideration to v2.0?)

Open mikependon opened this issue 4 years ago • 5 comments

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.

mikependon avatar Sep 18 '21 20:09 mikependon

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..

nandaccio avatar Nov 24 '21 14:11 nandaccio

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 avatar Feb 21 '22 07:02 w5l

@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 avatar Feb 21 '22 09:02 mikependon

@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.

ngardon avatar Dec 27 '22 11:12 ngardon

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.

mikependon avatar Dec 27 '22 12:12 mikependon