-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Re-implement the Tracing overall implementations - Addressing the Simplicity and Extensibility #941
Comments
This looks like a great simplification, and will save a lot of ceremonial code, especially since my use case is really only to ILogger the raw SQL to app insights for metrics & investigations. I understand the value of having string keys, (even though I don’t have a use case for a custom key)… but it would be good to not require clients to have to hard code literals for the default keys, so providing const values to use would be cleaner: instead of: this would be cleaner: |
@cajuncoding - thanks, but the purpose is to give this flexibility to the user. Imagine, you would like to call the In this case, was not it putting a constant class that holds the keys would again limit the implementations?
I am thinking that the library consumer would maintain their own trace keys. |
Sure I was affirming that the flexibility is great. I was only recommending to also offer the default keys as constants…to save all consumers from having to do this themselves, reduce room for error, and make the feature a little more intuitive! This should in no way reduce the flexibility of your design; only offer those that don’t use custom keys to not have to use string literals. Hope this helps clarify my recommendation. |
IKYDK. The thing in C# is, if you create an argument with a default value equals to whatever constant (either explicit value ("Insert") or implicit value (TraceKeys.Insert)) will still reflect as string literal "Insert" in the compiler 😄 (In which the TraceKeys.Insert = "Insert") |
Sure, the compiler will replace all instances of a constant with the literal. My recommendation was only concerning readability and even a little discoverability benefit….ultimately a set of provided constants for those default strings offers the flexibility you want (no less), and for those that use only those (not custom) then they have less maintenance and less risk of errors; in case it changes in RepoDb no updates are needed, and even if the constant name change and at least our compile would break letting us know. Whereby if we code our own constants, and something in RepoDb changes then then the code never complains and something could easily go unnoticed. I Hope this helps clarify. :-) |
@cajuncoding - no worry, this is not a big deal at all. We will introduce the |
Yep that makes sense! Thanks…yeah it’s a small thing but sometimes super useful. |
Other enhancements: First, I find it confusing that the "log.parameter" is actually the entity and not the parameters-collection... Maybe a better name (e.g. entity) would be preferable Second, it would be good to access the actual parameter collection for tracing/logging purpose |
@karli1 the log.Parameter property contains the accessible passed parameters to the actual execution. The type of this parameter could be differed based on the operation invoked. It could be any of the following.
The values are accessible anytime during the tracing. Hope this answer both of your questions. |
@mikependon Thank you for the clarification. Still, I would ask for both of my points.
|
@karli1 maybe it is time to revisit the implementation to enable the actual DbParameter itself. |
As an additional enhancement to this major refactoring, we have decided to rename and simplify the public IEnumerable<IDbDataParameter> Parameters { get; set; } Where in the future, can be used as below. public class MyCustomTrace : ITrace
{
public void Before(CancellableTraceLog log)
{
if (log.Key == "MyCustomKey")
{
foreach (var parameter in log.Parameters)
{
...
}
}
}
} Please share your thoughts and reservations. |
#941 Added the CancellableTraceLogTest class for Unit Testing.
Finalize the changes to the User Story #941
The changes and updates for this User Story will be available to next releases > RepoDB v1.13.0-alpha1. |
TL;DR Currently, the ITrace interface as being the base of all tracing capabilities, contains the methods that are equivalent to the existing extended operations for the
IDbConnection
.See below for the
Insert
operation.In the actual operation, inside the library, if the
trace
argument is passed with theITrace
object, we do call theBefore<Method>
BEFORE the actual execution. We also do call theAfter<Method>
AFTER the actual execution with some important information captured during the execution.The implementation is good and robust on its own and it is also addressing the operational-tracing scenarios if we are to look at it on the users POV.
Concerns
The current implementation is very close for extensibility in which it does not conform with the "O" on the SOLID principles. In addition to this, even though the user can trace the execution of the operations, but there is no way for the user to customize its own execution (on its own perusal/way).
We therefore found out that, the current implementation requires a major refactoring when it comes to implementation.
Proposal
To cover the simplicity of the implementations and the freedom of the tracing to the users of the library, we are planning to refactor the
ITrace
interface to only contains 2 methods.The method
BeforeExecution
stands as the entry point for all the operations BEFORE the actual execution towards the database. The methodAfterExecution
stands as the exit point of the existing operation AFTER the actual execution from the database.With this, a new property that handles the execution key is needed to be added into the TraceLog object, the base class for the argument that is being used for all the tracing (i.e.: CancellableTraceLog and TraceLog itself).
On the actual extended methods, the new argument named
traceKey
is also needed to be added to all the existing operations (i.e.: Insert, Delete, Update, Merge, etc)See the sample proposal code below.
In the
Insert
operation, we will add an additional argument namedtraceKey
. But the default value would be "Insert". In case the key is not passed, the "Insert" tracing will be executed.Then, when you call this operation, you as a user will have an option to pass your customized key. In the example below, you call a
TraceFactory.Create()
that creates an instance of your customizedITrace
object, and passing your own customized trace key.Sample code for your customized
ITrace
object.The implementation is very extensible and dynamic in the user's POV.
Drawbacks
This new proposal will create a breaking changes to those users who had already implemented the tracing on their solutions.
Mitigations
To avoid the breaking changes on the users POV, we can create a gist named TraceBase that would stand as the base trace object when tracing tracing all the operations.
Then, in the existing implementation (your class), you have to inherit this
TraceBase
class and have a minimal code change to override the existing method, instead of implementing theITrace
object.In short, instead of this...
Do this...
We are happy if the community of .NET could share their thoughts on this. 🙇🏼
The text was updated successfully, but these errors were encountered: