[Autumn] Dependency injection after ContextInitializer has done its part.
metaphore opened this issue · 6 comments
I have a case where I need to fill VerticalGroup
with a complex items and I chose to go with individual controller instance per view item to encapsulate view logic and item model reference within. So this controller class has a lot of similarities with ViewController
, like it has number of LML annotations and also should have injected dependencies to system-wide services/components.
I remember the discussion #40 and it gave me a good point to keep Context
not disposed in case I will need to obtain any system component in a future. And so I can, by calling Context#getComponent(Class<?>)
, but I start thinking if there is a way to automate this process. I mean in that fancy elegant way like ContextInitializer#initiateComponents()
does to resolve dependencies, but this time on demand for any specific instance with Autumn annotations like @Inject
(maybe even for @OnEvent
/@OnMessage
, but this could lead to memleaks due to an each instance should be unsubscribed manually).
ContextInitializer
is fully dedicated to only initialize Context
and is not usable after. Feels like if there should be some injector service, then it better be outside of ContextInitializer
and available system wide so anyone can utilize dependency injection later.
@czyzby what do you think, is it a good idea or even is it possible to add such utility functionality to the library core?
Well it is possible, no doubts. I just needed to copy most of the code from ContextInitializer
to process annotations. Which in fact made me feel that if dep. injection on demand could exist, it's probably not the worst idea to merge it into ContextInitializer
code somehow.
That's what providers are for. Annotate a class with @Provider
or implement DependencyProvider
directly. Initialize your objects using injected components and then call Context.provide
to create a new instance. See provider examples.
Thanks for pointing me out, after reading those examples, it seems like I'm still missing some base Autumn architectural concepts. So I see that Provider
is a good thing that I've been always ignoring.
Ok, so I should create Provider
for my ItemViewController
, and then call Context#provide(Class<T>)
to obtain a new instance. But still I have to inject all the dependencies manually inside the DependencyProvider#provide()
, right? Is there a simple way to obtain a new instance of Component
on demand, so I just annotate ItemViewController
's fields with Inject
and they get resolved automatically?
No, I don't believe so. Now that I think about it, there should be a @Provided
annotation for types, where it automatically registers a provider for you and uses constructor injection to create new objects.
Yeah, it could be a good solution. Feels like it will require some extra logic for Context
or those automatically created Provider
s, because right now there is no code to inject fields except for ContextInitializer
.
Should be very similar to converting current @Provider
's methods to provider instances - you'd just invoke constructors instead of methods. See ReflectionDependencyProvider
.