ComponentsManager
README for the 1.x.x of the library lives here.
Benefits
- No need to save the components somewhere
- No need to remove the component when the Activity/Fragment is going to be destroyed
- The components will be saved while the rotation changes
Getting started
This library is available on jitpack and jcenter.
To download it from the jitpack, add these lines in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
If you are using AndroidX
implementation "com.github.valeryponomarenko.componentsmanager:androidx:LATEST_VERSION"
If you are using AppCompat
implementation "com.github.valeryponomarenko.componentsmanager:appcompat:LATEST_VERSION"
Idea
The idea of the library is to save dagger components and return them when they are needed. Every component is saved in the static store and removed when the owner is going to be destroyed.
What's new
2.1.0
*InjectionManager
s have two new methods to find a component. The methods return null
if a component was not found and no exceptions are thrown.
// finds a component by type
XInjectionManager
.findComponentOrNull<SomeComponent>()
?.someMethod()
// finds a component by predicate
XInjectionManager
.findComponentOrNull { /* predicate */ }
?.someMethod()
The ComponentNotFoundException
class that is inside me.vponomarenko.injectionmanager.exeptions
package is deprecated, because the exeptions
was misspelled, so use ComponentNotFoundException
that is inside me.vponomarenko.injectionmanager.exceptions
package. The new ComponentNotFoundException
class is inherited from the old one.
2.0.1
If you use the *InjectionManager.findComponent()
method and the component was not found, the ComponentNotFoundException will be more informative, beucase the type of the component will be printed.
//before
Caused by: me.vponomarenko.injectionmanager.exeptions.ComponentNotFoundException:
Component for the Function1<java.lang.Object, java.lang.Boolean> was not found
...
//after
Caused by: me.vponomarenko.injectionmanager.exeptions.ComponentNotFoundException:
Component of the FragmentChildB type was not found
...
But if you use the *InjectionManager.findComponent(predicate)
method, the exception's massage will be the same as it was in 2.0.0.
2.0.0
The main difference between the 2.0.0 version and the 1.1.0 version that the IHasComponent interface is a generic one. Therefore, you must specify the class of the component.
//before
class MyFragment : Fragment(), IHasComponent {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
XInjectionManager
.bindComponent<MyComponent>(this)
.inject(this)
}
override fun getComponent(): Any = DaggerMyComponent.create()
}
//after
class MyFragment : Fragment(), IHasComponent<MyComponent> {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
XInjectionManager
.bindComponent(this)
.inject(this)
}
override fun getComponent(): MyComponent = DaggerMyComponent.create()
}
1.1.0
Add static methods into the (X/Compat)InjectionManager, so there will no need to get the instance and then call the needed method. Examples:
//before
fun foo() {
XInjectionManager.instance.init(this)
XInjectionManager.instance.bindComponent<AppComponent>(this)
}
//after
fun foo() {
XInjectionManager.init(this)
XInjectionManager.bindComponent<AppComponent>(this)
}
How to use
The following example will be for the AndroidX. If you want to use this library for the AppCompat packages, just change XInjectionManager to CompatInjectionManager.
First thing first, add the lifecycle callbacks listeners. At this step the library registers the lifecycle listener for the future activities and the fragments so the components that are bound to the activity or fragment will be destroyed right after the destruction of the owner.
class App : Application() {
override fun onCreate() {
super.onCreate()
XInjectionManager.init(this)
}
}
For example, the FirstFragment
(also it works for the activities too) has a component, so you must implement the IHasComponent
interface and call the bindComponent
method of the XInjectionManager
class. When the component is bound, it is available for other classes, but make sure, that these classes will not live longer than the owner of the component.
class FirstFragment : Fragment(), IHasComponent<FirstFeatureComponent> {
//code...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
XInjectionManager.bindComponent(this).inject(this)
}
override fun getComponent(): FirstFeatureComponent =
DaggerFirstFeatureComponent.builder()
.build()
}
If the fragment doesn’t have its own component and uses the AppComponent
to inject the dependencies, just call the findComponent method and specify the class of the component and that is all.
class SecondFragment : Fragment() {
//code...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
XInjectionManager.findComponent<AppComponent>().inject(this)
}
}
Also, this method might be used for getting dagger dependencies to build some components.
class AnotherFragment : Fragment(), IHasComponent<AnotherFeatureComponent> {
//code...
override fun getComponent(): AnotherFeatureComponent =
DaggerAnotherFeatureComponent.builder()
.appDependency(XInjectionManager.findComponent())
.build()
}
That's all. There is no need to write code that will save, search or remove components anymore.
For more information, please, read the wiki pages.
Links
Lifecycle aware Dagger components - ProAndroidDev
If you have any questions, feel free to ask me on LinkedIn.