GithubHelp home page GithubHelp logo

afollestad / ulfberht Goto Github PK

View Code? Open in Web Editor NEW
251.0 10.0 8.0 688 KB

๐Ÿ—ก๏ธ A small but powerful & opinionated DI library. Written in Kotlin, and powered by annotation processing.

Home Page: https://af.codes

License: Apache License 2.0

Kotlin 100.00%
kotlin di dependency-injection annotation-processor viewmodel lifecycle

ulfberht's Introduction

ulfberht's People

Contributors

afollestad avatar alorma avatar houssemzaier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ulfberht's Issues

Child components should be assigned from parents

Instead of:

@Component
interface Parent

@Component(parent = Parent::class)
interface Child

It's more maintainable and searchable to have:

@Component(
  children = [Child::class]
)
interface Parent

@Component
interface Child

Provider<> injection

Injecting the internal Provider<> interface for a given type should be supported like it is for Dagger.

Improve @Provides circular dependency detection

Below, SomeClass<String, Boolean> includes OneImpl in its @Provides method. OneImpl injects SomeClass<String, Boolean> into its constructor.

@Module
interface MyModule1 {
  @Binds fun one(one: OneImpl): One

  @Binds fun two(two: TwoImpl): Two
}

@Module
abstract class MyModule2 {
  @Provides fun one(one: OneImpl): SomeClass<String, Boolean> = SomeClass("test", true)

  @Provides fun two(two: TwoImpl): SomeClass<Int, Long> = SomeClass(6, 10L)
}

interface One {
  fun doSomething()
}

class OneImpl(
  private val two: Two,
  private val idk: SomeClass<String, Boolean>
) : One {
  override fun doSomething() = two.doSomething()
}

Constructor Injection

This is an issue to request for direct constructor injection.
Currently the @Inject functionality cannot be used on the constructor of a class.

Current behaviour:

data class DependencyA

data class MyClass constructors (
     val dependencyA: DependencyA
)
@Module
abstract class DependencyProvider {
     @Provides
     fun provideMyClass(dependencyA: DependencyA) = MyClass(dependencyA)
}

Expected behaviour:

data class MyClass @Inject constructor (
     dependencyA: DependencyA
)

@IntoSet capabilities

A simple case:

@Module
abstract class MyModule1 {
  @Provides @IntoSet 
  fun stringOne(): String = "hello"
}

@Module
abstract class MyModule2 {
  @Provides @IntoSet 
  fun stringTwo(): String = "world!"
}

...

@Inject lateinit var strings: Set<String> // ["hello", "world!"]

A qualified case:

@Module
abstract class MyModule1 {
  @Provides @IntoSet @HelloWorld
  fun stringOne(): String = "hello"
}

@Module
abstract class MyModule2 {
  @Provides @IntoSet @HelloWorld
  fun stringTwo(): String = "world!"
}

...

@Inject @HelloWorld lateinit var strings: Set<String>
@Inject @HelloWorld lateinit var providedStrings: Set<Provider<String>>
@Inject @HelloWorld lateinit var providedStrings: Provider<Set<String>>
@Inject @HelloWorld lateinit var providedStrings: Provider<Set<Provider<String>>>

Android ViewModel injection

When view model types are injected, they should be associated with a view model factory for the injector.

Multi-module dependency injection

I have seen that currently, Google provides us with the dynamic feature module to separate features in separate modules. Will this library support multi-module dependency injection?

Circular dependency detection

Circular dependency detection is needed, with build-time error messaging.


interface One
class OneImpl(val two: Two) : One

interface Two
class TwoImpl(val one: One) : Two

When we get One, we have to get Two. When we get Two, we have to get One. This creates a paradoxical loop.

One -> Two -> One -> Two -> ...


  1. Through @Binds
@Module
interface SomeModule {
   @Binds fun bindOne(impl: OneImpl): One

   @Binds fun bindTwo(impl: TwoImpl): Two
}

ModuleBuilder should detect this by looking at the constructors of OneImpl and TwoImpl, comparing parameter types recursively.

  1. Through @Provides
@Module
abstract class SomeModule {
   @Provides fun provideOne(two: Two): One = OneImpl(two)

   @Provides fun provideTwo(one: One): Two = TwoImpl(one)
}

ModuleBuilder should detect this by simply looking at the parameters of each provide method and comparing recursively.


Comparing recursively above can be important for situations like this:

interface One
class OneImpl(val two: Two) : One

interface Two
class TwoImpl(val three: Three) : Two

interface Three
class ThreeImpl(val one: One) : Two

One -> Two -> Three -> One -> Two -> Three -> ...

Kotlin Native support

Is there anything stopping this library from supporting native targets? It would be cool to have true dependency injection support on native. Currently, the only di library for native targets is Kodein and that is service lookup library and not true di.

@IntoMap capabilities

A simple case:

@Module
abstract class MyModule1 {
  @Provides @IntoMap("one") 
  fun stringOne(): String = "hello, "
}

@Module
abstract class MyModule2 {
  @Provides @IntoMap("two")
  fun stringTwo(): String = "world!"
}

...

@Inject lateinit var strings: Map<String, String> // ["one": "hello, ", "two": "world!"]

A qualified case:

@Module
abstract class MyModule1 {
  @Provides @IntoMap("test", "one") 
  fun stringOne(): String = "hello, "
}

@Module
abstract class MyModule2 {
  @Provides @IntoMap("test", "two") 
  fun stringTwo(): String = "world!"
}

...

@Inject("test") lateinit var strings: Map<String, String> // ["one": "hello, ", "two": "world!"]

Upgrade generics support

Take this module:

@Module
abstract class Module {
  @Provides fun someClass1(): SomeClass<String, Boolean>

  @Provides fun someClass2(): SomeClass<Int, Long>
}

The generated code should be able to differentiate between these two return types and inject them correctly.

Add plugin capabilities

Android logic, like lifecycles and view models, should not be in the core/processor modules. The processor should be able to find plugins by an annotation and pull out logic.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.