Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you inject subcomponent factory #49

Closed
matejdro opened this issue Oct 17, 2024 · 6 comments · Fixed by #64
Closed

How do you inject subcomponent factory #49

matejdro opened this issue Oct 17, 2024 · 6 comments · Fixed by #64
Assignees
Labels
enhancement New feature or request

Comments

@matejdro
Copy link

Maybe a bit stupid question, but I've been trying to figure out how to actually inject the factory into something to instantiate the subcomponent:

@Component
@MergeComponent(AppScope::class)
@SingleIn(AppScope::class)
interface AppComponent : AppComponentMerged {
    fun provideRendererUsage(): RendererUsage
}

@ContributesSubcomponent(LoggedInScope::class)
@SingleIn(LoggedInScope::class)
interface RendererComponent {

    @ContributesSubcomponent.Factory(AppScope::class)
    interface Factory {
        fun createRendererComponent(argument: String): RendererComponent
    }
}

Inject
class RendererUsage(rendererComponentFactory: RendererComponent.Factory)

But above fails with Cannot find an @Inject constructor or provider for: RendererComponent.Factory

@vRallev vRallev added the help wanted Extra attention is needed label Oct 17, 2024
@vRallev
Copy link
Contributor

vRallev commented Oct 17, 2024

AppComponent will implement the Factory interface. You cannot inject components themselves, therefore you cannot inject Factory. Simply take the AppComponent and call the createRendererComponent() function on it.

@matejdro
Copy link
Author

That kinda breaks the non-centralised nature of Anvil, since you still need access to the component instance to create subcomponents.

Is this a fault of kotlin-inject-anvil or kotlin-inject?

@vRallev
Copy link
Contributor

vRallev commented Oct 17, 2024

kotlin-inject, but it's the same in Dagger. You need the reference to the component for the parent-child relationship of the components. There's no way around it. Think of the @Factory annotation the same way as a @ContributesTo annotation.

@matejdro
Copy link
Author

matejdro commented Oct 18, 2024

Doh, the solution is just to add a @Provides function to your main component, that points to itself, which allows injection of it anywhere.

   @Provides
   fun provideRendererSubcomponentFactory(): RendererComponent.Factory = this

do you think it would be a good idea to add this to the README? I can make a PR if necessary.

but it's the same in Dagger

I'm pretty sure that with Dagger's Anvil, you can directly inject subcomponent factories.

@vRallev
Copy link
Contributor

vRallev commented Oct 18, 2024

To be honest, I never tried this 🙃 Instead of updating the README, this function should be generated.

@vRallev vRallev reopened this Oct 18, 2024
@vRallev vRallev added enhancement New feature or request and removed help wanted Extra attention is needed labels Oct 18, 2024
@vRallev vRallev self-assigned this Oct 28, 2024
vRallev added a commit that referenced this issue Oct 28, 2024
Generate a binding method for types annotated with `@ContributesSubcomponent.Factory` in the parent scope. This allows us to inject the factory type itself.

Fixes #49
vRallev added a commit that referenced this issue Oct 28, 2024
Generate a binding method for types annotated with `@ContributesSubcomponent.Factory` in the parent scope. This allows us to inject the factory type itself.

Fixes #49
@matejdro
Copy link
Author

matejdro commented Nov 4, 2024

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants