<@UD8KZJQUF> find() is programatic dependency inje...
# tornadofx
c
@Shan find() is programatic dependency injection for TornadoFX. You can also inject dependencies statically using "by inject()" on a declaration. Dependency Injection, in general and not just with TornadoFX, lets you wire up object graphs. This avoids a cascading set of special constructors and setters that might be needed for a given object to properly function. By object graph, I mean a complex object that references other objects (which in turn reference other objects). It's definitely feasible to do this by hand, especially if the object graph is shallow. However, industry-wide, many are have seen deeper object graphs become a source of maintenance problems as different developers come up with different ways to hook everything up. You'll see DI in the Spring framework, JavaEE EJBs, and web technologies like Angular. In your case, find<MyFragment>() instantiates a new object. However, if you call find<MyView>(), a new object may not be instantiated. That can be overridden, but it seems to be a guiding convention in this group. DI lets you control the scope of the object (ex "just this once" versus "app-wide").
s
Thanks for the explanation @carlw. I guess my current issue with injections is that it's a lot less readable to me than just using constructor chains, but the scoping provided when injecting with tfx is something I wasn't aware of. In my program I'm setting up coroutine scopes within certain views/fragments by creating a custom
ScopedView
abstract class that implements a
CoroutineScope
interface, and then extend my views/fragments I need with a coroutines scope from there. It seems like tfx has already implemented the same sort of idea with tfx's custom scoping.
If you don't mind, do you know how exactly instantiating a fragment by
inject()
rather than normal instantiation affects the lifecycle calls? I can't seem to find any information about it in the wiki or in the dokka docs.
Since using
find<MyFragment>()
instantiates the fragment every time (as opposed to find<MyView>() which will find it if it's already instantiated from what I understand via your explanation) I would expect the fragment's
onDock()
to get called when using normal instantiation methods as well, but I might be missing something.
c
the onDock() refers to the lifecycle of a JavaFX Stage object. Just instantiating Stage, or Scene, or VBox, doesn't get the underlying onShowing or onShown called. These are lifecycle events that map to onDock
they're important because at the point of instatiation -- DI or otherwise -- the OS hasn't allocated a window and therefore, there is not screen geometry and other calculations that developers often depend on
s
Ah, I see. So it makes sense that
onDock()
gets called for when I instantiate my view, but not my fragment, as I'm not creating a new stage.
Thanks for your help!
c
Sure. take a look at App if you want to see how the first Stage is created and shown