Hey there, fellow Android developers! 👋 Are you tired of the hassle that comes with managing assisted injection in your modular app? Well, buckle up because I've got some exciting news for you! 🚀 Introducing Anvil Utils - a game-changing library that will make your life easier when working with Dagger and Anvil in multi-module projects. The Struggle Is Real Picture this: you have a beautifully architected modular app with api and implementation modules per feature. Everything is going smoothly until you encounter a situation where your feature contains a factory for an entity and want to expose it in an api, and you need to make this factory available within the Dagger graph. 😰 Let's walk through the ways to do that. Bare Dagger Approach For instance, you have such public API for your feature module: interface MyClass { interface Factory { fun create(param1: String, param2: Int): MyClass } } Traditionally, you'd have to manually create an @AssistedFactory in the implementation module, inherit from the public interface in the API module, and write a Dagger module which binds assisted factory to it's public interface. Also, you would need to maintain both factory interfaces - public one and implementation one. Here's an example: class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } @Module interface MyClassFactoryBindingModule { @Binds fun bindFactory(impl: DefaultMyClass.Factory): MyClass.Factory } Seems like a lot of work, doesn't it? Let's make it easier to maintain step by step Introducing Anvil Anvil is a Kotlin compiler plugin which helps to drastically reduce the boilerplate needed to use Dagger 2 in your application. Also, if properly configured, it can improve build times in your application by removing the requirement to run Dagger 2 annotation processor in your feature modules. I will not dive deep into what Anvil is and why you should consider using it. That's a topic for another day. Please read through the Anvil readme here to get what it is about. https://github.com/square/anvil Thanks to Anvil, you can get rid of the binding module using @ContributesBinding: class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @ContributesBinding(AppGraph::class, MyClass.Factory::class) @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } Anvil will generate corresponding module which will bind DefaultMyClass.Factory to MyClass.Factory for you. This lowers the amount of boilerplate, but it's still there! You have to manually keep public factory interface and implementation interface aligned with the constructor! Can we go further and reduce the amount of work needed to support this use case? Sure! @ContributesAssistedFactory to the Rescue! Fear not, my friend! With Anvil Utils, you can say goodbye to the manual labor of creating assisted factories. The @ContributesAssistedFactory annotation is here to save the day! 🦸♂️ This powerful annotation automatically generates assisted factories for your annotated classes and contributes them to the specified scope as bindings of the provided factory type. It's like having a personal assistant that takes care of all the heavy lifting for you! You now can remove the @AssistedFactory interface completely and annotate the DefaultMyClass with @ContributesAssistedFactory: @ContributesAssistedFactory(AppGraph::class, MyClass.Factory::class) class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass And voila! Anvil Utils will generate the necessary assisted factory for you, without breaking a sweat. 😎 In the Wild Example To demonstrate the power of this library, I've made a huge pull request to beautiful open-source project - companion app for the Flipper - Tamagochi for hackers. Please, take a look if you're interested: https://github.com/flipperdevices/Flipper-Android-App/pull/79 Embrace the Power of Anvil Utils So, what are you waiting for? Give Anvil Utils a try in your next modular Android project and experience the joy of hassle-free assisted injection. Your codebase will thank you, and your fellow developers will be in awe of your newfound superpowers! 💪 Happy coding, and may the power of Anvil Utils be with you! 🚀 P.S. Don't hesitate to open feature requests - I'm eager to improve the library and add more features. Hey there, fellow Android developers! 👋 Are you tired of the hassle that comes with managing assisted injection in your modular app? Well, buckle up because I've got some exciting news for you! 🚀 Introducing Anvil Utils - a game-changing library that will make your life easier when working with Dagger and Anvil in multi-module projects. Anvil Utils Anvil Utils Anvil The Struggle Is Real Picture this: you have a beautifully architected modular app with api and implementation modules per feature. Everything is going smoothly until you encounter a situation where your feature contains a factory for an entity and want to expose it in an api , and you need to make this factory available within the Dagger graph. 😰 api implementation api Let's walk through the ways to do that. Bare Dagger Approach For instance, you have such public API for your feature module: interface MyClass { interface Factory { fun create(param1: String, param2: Int): MyClass } } interface MyClass { interface Factory { fun create(param1: String, param2: Int): MyClass } } Traditionally, you'd have to manually create an @AssistedFactory in the implementation module, inherit from the public interface in the API module, and write a Dagger module which binds assisted factory to it's public interface. Also, you would need to maintain both factory interfaces - public one and implementation one. Here's an example: @AssistedFactory class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } @Module interface MyClassFactoryBindingModule { @Binds fun bindFactory(impl: DefaultMyClass.Factory): MyClass.Factory } class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } @Module interface MyClassFactoryBindingModule { @Binds fun bindFactory(impl: DefaultMyClass.Factory): MyClass.Factory } Seems like a lot of work, doesn't it? Let's make it easier to maintain step by step Introducing Anvil Anvil is a Kotlin compiler plugin which helps to drastically reduce the boilerplate needed to use Dagger 2 in your application. Anvil Also, if properly configured, it can improve build times in your application by removing the requirement to run Dagger 2 annotation processor in your feature modules. I will not dive deep into what Anvil is and why you should consider using it. That's a topic for another day. Please read through the Anvil readme here to get what it is about. https://github.com/square/anvil https://github.com/square/anvil Thanks to Anvil, you can get rid of the binding module using @ContributesBinding : @ContributesBinding class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @ContributesBinding(AppGraph::class, MyClass.Factory::class) @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass { @ContributesBinding(AppGraph::class, MyClass.Factory::class) @AssistedFactory interface Factory: MyClass.Factory { override fun create(param1: String, param2: Int): DefaultMyClass } } Anvil will generate corresponding module which will bind DefaultMyClass.Factory to MyClass.Factory for you. Anvil DefaultMyClass.Factory MyClass.Factory This lowers the amount of boilerplate, but it's still there! You have to manually keep public factory interface and implementation interface aligned with the constructor! Can we go further and reduce the amount of work needed to support this use case? Sure! @ContributesAssistedFactory to the Rescue! Fear not, my friend! With Anvil Utils , you can say goodbye to the manual labor of creating assisted factories. The @ContributesAssistedFactory annotation is here to save the day! 🦸♂️ Anvil Utils Anvil Utils @ContributesAssistedFactory This powerful annotation automatically generates assisted factories for your annotated classes and contributes them to the specified scope as bindings of the provided factory type. It's like having a personal assistant that takes care of all the heavy lifting for you! You now can remove the @AssistedFactory interface completely and annotate the DefaultMyClass with @ContributesAssistedFactory : @AssistedFactory DefaultMyClass @ContributesAssistedFactory @ContributesAssistedFactory(AppGraph::class, MyClass.Factory::class) class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass @ContributesAssistedFactory(AppGraph::class, MyClass.Factory::class) class DefaultMyClass @AssistedInject constructor( @Assisted param1: String, @Assisted param2: Int ) : MyClass And voila! Anvil Utils will generate the necessary assisted factory for you, without breaking a sweat. 😎 Anvil Utils Anvil Utils In the Wild Example To demonstrate the power of this library, I've made a huge pull request to beautiful open-source project - companion app for the Flipper - Tamagochi for hackers. Please, take a look if you're interested: https://github.com/flipperdevices/Flipper-Android-App/pull/79 https://github.com/flipperdevices/Flipper-Android-App/pull/79 Embrace the Power of Anvil Utils So, what are you waiting for? Give Anvil Utils a try in your next modular Android project and experience the joy of hassle-free assisted injection. Your codebase will thank you, and your fellow developers will be in awe of your newfound superpowers! 💪 Anvil Utils Anvil Utils Happy coding, and may the power of Anvil Utils be with you! 🚀 Anvil Utils Anvil Utils P.S. Don't hesitate to open feature requests - I'm eager to improve the library and add more features. P.S.