Tracer annotations package is pers.shawxingkwok.tracer
rather than that in videos.
Introduction #
The pictures above highlight the disadvantages of the general model style. Now, with Kotlin-JVM
, KSP
,
and minimal configuration, Tracer
generates extensional properties oriented toward internal traceable
elements, which realizes dependency injection in a novel way.
Tracer
has several main advantages over common DI tools, as listed below:
- Minimal configuration.
- Powerful: generic types and variances are parsable, and it can trace super types as well.
- Fast: operates without runtime cache or reflection.
Contents below tell how Tracer
models and extends relationships as shown in the top picture.
Root #
Each class with @Tracer.Root
is considered as the trace start point, followed by its interior
public/internal elements.
Annotate the source class (
House
in this case) withTracer
annotations.Build.
Model with the generated tracer interfaces (
HouseTracer
).Rebuild. There generates element traces as below.
Inject
The renaming problem could be solved by an IDE plugin that has not come out yet.
Nodes #
There are some traced properties with the same type. If all their interior properties are traced with recurse from the root class, the generated traces would be huge and chaotic. Considering from a different perspective, repeatedly constructed objects should maintain independence in design, so that they do not require deep exploration when called. Take the example of a car model, you might access the cost of the wheels from the outside, but there is no need to drill down to the specific prices of the tires and axles.
Now we add one bedroom and its some inner objects as below. As nodes grow on root or other nodes,
Door
LivingRoom
and WifiRouter
are all built once and each of them represents node;
Bedroom
is repeatedly built and represents nodes.
Now objects in the left picture are traced in the file HouseElements
, and objects in the right picture
are traced in the file BedroomElements
. Note that, OuterHouseTracer
is extended by BedroomTracer
, making
HouseElements
starting with double _
acquirable from BedroomTracer
.
Generated code
Tip #
Tracer.Tip
represents the trace end, which means the carrier’s elements are never traced.
Context and the tracer interface are needless in a simple test.
Elements or their type classes with features below are also considered as trace ends, meaning
they are never traced insides. Like classes with Tracer.Root
, they should be designed independently
and avoid being exploring too insides.
Tracer.Root
,Tracer.Nodes
- Interface, enum, object
- Nullable
- Foreign (from other modules, generated code, or Java files)
- Rebuilt symbols
- Constructor is not single and empty.
- Generic
- Abstract / open
Those x
are not traced.
Omit #
Properties
and super types
with @Tracer.Omit
would be omitted, which is generally used
with some unsupported new syntaxes, like context receiver
.
Super type trace rules are later explained on page ‘Details’.
Source code
i
with context receiver
is omitted in generated code now.Tracer interfaces
are not essential to implement in simple tests.