question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add ability to inject abstract @AssistedInject

See original GitHub issue

I have a use case while I have to inject the abstract class, not the implementation itself, but the implementation requires an assisted parameter to be injected, like this:

class ClassAImpl @AssistedInject constructor(
    @Assisted private val params: ClassAParams
) : ClassA {

    ....

    @AssistedFactory
    interface ClassAFactory {

        fun create(params: ClassAParams): ClassA
    }
}

I got this error:

An assisted factory's abstract method must return a type with an @AssistedInject-annotated constructor.

While it should work fine

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
tbroyercommented, Aug 23, 2021

Just because the ClassAFactory is nested into ClassAImpl does not mean Dagger will extrapolate anything from that: it sees an @AssistedFactory interface whose abstract methods returns a ClassA, whose constructor is (apparently) not annotated with @AssistedInject. Dagger has no means to know that you actually would like that factory to return a ClassAImpl instance rather than any other ClassA subclass (or ClassA itself if not abstract)

Because you don’t inject either ClassA or ClassAImpl instances, but only ClassAFactory, you can declare the method to return ClassAImpl, and then it should Just Work™.

If you don’t want to expose the detail that this will be a ClassAImpl instance, and really want injection points to only know about ClassA, then make an interface for ClassA, and then have the @AssistedFactory extend it and override the method to tighten its return type, and then finally add a binding for those interfaces so Dagger will actually inject a ClassAImplFactory whenever a ClassAFactory is needed:

// This is your "public API"
interface ClassAFactory {
    fun create(params: ClassAParams): ClassA
}

// This is an implementation detail for Dagger
interface ClassAImplFactory : ClassAFactory {
    override fun create(params: ClassParams): ClassAImpl
}

// Add that to your @Module
@Binds fun bindClassAFactory(factory: ClassAImplFactory): ClassAFactory

// This will actually receive a ClassAImplFactory, so create(params) will return a ClassAImpl instance
@Inject lateinit var classAFactory: ClassAFactory

(this should work in theory, but I haven’t tested it, so maybe there are limitations in Dagger that would prevent it from working)

0reactions
udamastercommented, Apr 15, 2022

Yep, got it to work …that was the prob. Thanks

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can I use some kind of assisted Inject with Dagger?
I wrote about it in this blogpost, but I'll add a full example here to make things easier. First thing you need are...
Read more >
Assisted Injection - Dagger
This can be done by adding a name via the @Assisted("name") annotation. These must be put on both the factory method and the...
Read more >
Assisted Injection for Dagger - Google Groups
I have a class that gets some dependencies from the object graph, and other dependencies from a caller at runtime. It's like a...
Read more >
extensions/assistedinject/src/com/google/inject ... - Google Git
All the data necessary to perform an assisted inject. */ ... .add("implementation type", implementationType) ... "%s is abstract, not a concrete class.
Read more >
Connecting The Dots: Dagger • ViewModel • Saved State
Dagger 2.31 added @AssistedInject functionality and therefore the setup is simplified ... Now, you want to fully use power of ViewModels, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found