InflationInject
InflationInject copied to clipboard
MembersInjector for late injection
AssistedInject only works for construction injection.
Dagger on the other hand is able to inject stuff after construction with *_MembersInjector
for some @Inject lateinit var dep: Dependency
.
Is it somehow possible to have this for AssistedInject?
This is not possible with the library, no. But you don't really need a library to do this. You can members inject the instance and then set whatever other fields you want directly.
The reason assisted inject only works for constructor injection is that you cannot ask Dagger to partially call a constructor and then partially supply the other arguments.
-
I understand that you don't need the library to do this and can somehow set fields manually, but since Dagger allows this, doesn't AssistedInject kind of breaks the feature?
-
I'm not sure if I understand your second point.
But.
In the generated factory, there could be added MembersInjector<TheClass>
and after instantiating the class, just call injectMembers
on it?
public final class TheClass_AssistedFactory implements TheClass.Factory {
private final Provider<ConstructorDep> constructorDep;
private final MembersInjector<TheClass> membersInjector;
@Inject
public TheClass_AssistedFactory(
Provider<ConstructorDep> constructorDep,
MembersInjector<TheClass> membersInjector) {
this.constructorDep = constructorDep;
this.membersInjector = membersInjector;
}
@Override
public MViewModel create(AssistedDep assistedDep) {
TheClass obj = new TheClass(
constructorDep.get(),
assistedDep);
membersInjector.injectMembers(obj);
return obj;
}
}
Nice thing about this is, that if you don't have any @Inject lateinit var
inside the class, Dagger will use NoOpMembersInjector.INSTANCE
which does nothing and also if there's have inheritance, it will include the base member injectors.
Or shouldn't there be at least some warning?
Oh, you're saying you want members injection to be performed on constructor-injected types? I see. I suppose that's reasonable for consistency of behavior.
I thought you wanted assisted injection on a type that was solely members injected.
Can I ask why you are doing this? Members injection is a truly terrible thing.
I agree, members injection seems like a terrible thing.
The reason is android ViewModel with inheritance:
- we have "pure" Dagger with ViewModels
- all ViewModels inherit from some
BaseViewModel
class - for some historical reason (🤷♂ ) there's members injection in the
BaseViewModel
, therefore when inheriting from the base, it doesn't need to have inject param in all inherited constructors - we'd like to add
AssistedInject
to the project, so that we can useSavedStateHandle
- if we do that, you never can access the members injection.
I know, that it seem like a terrible thing, but also if (for some reason) you have members injection without inheritance, it's the same - no warning, crashes at runtime.
I was checking briefly how the MembersInjector works and for specific class it includes even parent MembersInjector, e.g for SomeViewModel
inheriting BaseViewModel
, it properly injects SomeViewModel
dependencies and also BaseViewModel
dependencies.
This means, that injecting MembersInjector<TheClass>
into generated factory should (?) be safe and sufficient.
So one trouble here is that AssistedInject is not Dagger-specific and thus cannot depend on the MembersInjector
type. It's purely a javax.inject-based injector, at least in the core.
I see the issue. I was thinking, that it would be possible to extend the pure AssistedInject processor to generate the code, but then not sure, how to pass the information about what to generate.
a) pass some data from module to module somehow?
b) AssistedInjectDagger2Processor
would generate another annotation for the members injection which AssistedInjectProcessor
would parse and generated the data
I don't like either option, but not sure how else could be solved
FYI this is no longer a problem as AssistedInjection has moved to Dagger and all that's left is inflation injection. We can add special handling for MembersInjector
now.