kotlin-inject

Dependency injection lib for kotlin

APACHE-2.0 License

Stars
1.2K

Bot releases are hidden (Show)

kotlin-inject - 0.7.1 Latest Release

Published by evant 4 months ago

[0.7.1] 2024-06-12

Fixed

  • Removed erroneous @KmpComponentCreator annotation.
kotlin-inject - 0.7.0

Published by evant 4 months ago

[0.7.0] 2024-06-12

Changed

  • @Scope annotations now take arguments into account. This means for example, if you have
    @Scope
    annotation class NamedScope(val value: String)
    
    then the scope: @NamedScope("one") and @NamedScope("two") would be treated as distinct. Previously they were
    treated as the same scope.
  • Legacy implicit assisted injection (not using the @Assisted annotation) is now an error.
  • The build will now fail if multiple qualifiers are applied in the same place, instead of picking the first one. This
    applies both to the new annotation (see below) and javax.inject.Qualifier. A minor exception is you are allowed to
    have one of each type to aid in migration. In that case the me.tatarka.inject one will be chosen.

Added

  • Added a me.tatarka.inject.annotations.Qualifier annotation as an alternative to using typealias. For example, you
    could do:
    @Qualifier
    annotation class Named(val value: String) 
    
    @Inject
    class MyClass(@Named("one") val one: String, @Named("two") val two: String)
    
    @Component
    abstract class MyComponent {
      abstract val myClass: MyClass
    
      @Provides @Named("one")
      fun provideOne(): String = "one"
    
      @Provides @Named("two")
      fun provideTwo(): String = "two" 
    }
    
    This behaves the same as javax.inject.Qualifier does when you have me.tatarka.inject.enableJavaxAnnotations=true.
  • Added a new @KmpComponentCreate annotation for nicer multiplatform support. This allows you to create component
    instances from common code when generating platform-specific outputs.
    // src/commonMain
    @Component
    abstract class MyKmpComponent
     
    @KmpComponentCreate
    expect fun createKmp(): MyKmpComponent
    
    see the new multiplatform docs for more details.
  • You can now use an @Inject annotation on an inner class provided the outer class can be provided.
    @Inject class Outer { @Inject inner class Inner }
    
    @Component abstract class MyComponent { abstract val inner: Outer.Inner }
    

Removed

  • The KAPT backend is removed, please migrate to KSP if you haven't already.

Fixed

  • Fixed cases of invalid code generation (#321, #337, #313).
  • Fixed an exception thrown on KSP2 when running multiple rounds (google/ksp#1854).
  • Fixed various issues with handling method overrides in components (#309, #375)
  • Allow scope annotations on both an interface and component implementation if they are the same scope (#320).
kotlin-inject - v0.6.3

Published by evant about 1 year ago

[0.6.3] 2023-09-02

Fixed

  • Fixed scoped assisted injection enforcement. It was incorrectly using the component scope instead of the scope of the
    assisted class or provides method.
kotlin-inject - v0.6.2

Published by evant about 1 year ago

[0.6.2] 2023-08-28

Changed

  • Updated kotlin to 1.9.0
  • If a dependency's scope is not found on the component providing it, a better error message is given.
  • Adding a @Provides annotation on an abstract fun or val will now warn that it has no effect.
  • When overriding a method the parent is checked to see if it has a @Provides annotation. This makes the example in
    the README actually work:
    @NetworkScope abstract class NetworkComponent {
      @NetworkScope @Provides abstract fun api(): Api
    }  
    @Component abstract class RealNetworkComponent : NetworkComponent() {
      // This is now treated as a @Provides even if not annotated directly
      override fun api(): Api = RealApi()
    }
    

Fixed

  • Typealiases are treated as separate types in multibinding. This is consistent with other
    uses of typealiases.

    For example:

    typealias MyString = String
    
    @Component abstract class MyComponent {
      abstract val stringItems: Set<String>
      abstract val myStringItems: Set<MyString>
    
      @Provides @IntoSet fun stringValue1(): String = "string"
    
      @Provides @IntoSet fun stringValue2(): MyString = "myString"
    }
    

    stringItems will contain {"string"} and myStringItems will contain {"myString"}.

  • Lambda types now work in set multibindings.

    @Component abstract class MyComponent {
      abstract val lambdaSet: Set<() -> String>
    
      @Provides @IntoSet fun lambda1(): () -> String = { "one" }
    
      @Provides @IntoSet fun lambda2(): () -> String = { "two" }
    }
    
  • Assisted injection no longer works with scopes or cycles. These two cases would over-cache the instance, ignoring the
    assisted arguments. They now throw an error instead.

     // now throws cycle error when providing
    @Inject class AssistedCycle(val factory: (Int) -> AssistedCycle, @Assisted val arg: Int)
    // now throws error when providing
    @MyScope @Inject class AssistedScoped(@Assisted val arg: Int)
    
  • Fixed edge case where accessing a parent scoped dependency from a lazy cycle generated invalid code.

kotlin-inject - v0.6.1

Published by evant over 1 year ago

[0.6.1] 2023-02-11

Fixed

  • Fixed code generation issues with assisted injection.
kotlin-inject - v0.6.0

Published by evant over 1 year ago

[0.6.0] 2202-12-21

Changed

  • Added the ability to explicitly mark assisted injection parameters with an @Assisted annotation. Not providing them
    will currently warn which will become an error in the future. This allows better documentation on which params are
    injected and which ones are provided by the caller. It also allows more flexibility for parameter ordering, you can
    put the assisted params at the start instead of at the end if you so choose.

    For example, if you have:

    @Inject class AssistedClass(arg1: One , arg2: Two, arg3: Three)
    @Inject Usage(createAssistedClass: (Two, Three) -> AssistedClass)
    

    you should update it to:

    @Inject class AssistedClass(arg1: One , @Assisted arg2: Two, @Assisted arg3: Three)
    

Fixed

  • @Inject annotations being ignored if used through a typealias, ex:
    typealias MyInject = Inject
    @MyInject class MyClassToInject
    
kotlin-inject - v0.5.1

Published by evant about 2 years ago

[0.5.1] 2022-07-05

Fixed

  • Fixed dependency resolution issue with native artifacts
kotlin-inject - v0.5.0

Published by evant about 2 years ago

[0.5.0] 2022-07-02

Changed

  • The kapt backend is now deprecated and will be removed in a future release. Please migrate to ksp instead.

  • Introduced some stricter checks to catch issues with certain graph setups. This may cause graphs that compiled before
    to no longer compile. Specifically:

    @MyScope @Component abstract class ParentComponent
    @MyScope @Component abstract class ChildComponent(@Component val parent: ParentComponent)
    

    will fail with:

    Cannot apply scope: @MyScope ChildComponent
    as scope @MyScope is already applied to parent ParentComponent
    

    as it's ambiguous what the lifetime of the given scope should be. And:

    @Component abstract class ParentComponent {
      @Provides fun foo(bar: Bar): Foo = ...
    } 
    @Component abstract class ChildComponent(@Component val parent: ParentComponent) {
      abstract val foo: Foo
      @Provides fun bar(): Bar = ...
    }
    

    will fail with:

    Cannot find an @Inject constructor or provider for: Bar 
    

    In other words a parent component can no longer depend on a dependency provided by a child component. Not only does
    this lead to confusing graphs, but it can lead to memory leaks if the parent component lives longer than the child and
    ends holding on to that child dependency.

Added

  • You can now use function and Lazy types in Set. This allows you to lazily construct its entries without having to
    change the type on your @IntoSet methods.
    @Component abstract class MyComponent {
      val funSet: Set<() -> Foo>
      val lazySet: Set<Lazy<Foo>> 
      
      @Provides @IntoSet fun foo1(): Foo = ...
      @Provides @IntoSet fun foo2(): Foo = ...
    }
    

Fixed

  • Fixed issue with name collisions when generating arguments. This could cause invalid code to be generated as the inner
    arg would shadow the outer arg that was attempted to be used.
  • Improved the error message for scoped provides in unscoped component.
  • Fixed printing of an inner type to include the outer class. i.e. You will now get Parent.Child in error messages
    instead of just Child which can make it easier to find the location of the error.
kotlin-inject - v0.4.1

Published by evant almost 3 years ago

[0.4.1] 2022-01-01

Changed

  • Improved generated code formatting.
  • Removed explicit retention annotation to get rid of kotlin js warnings.

Fixed

  • Fixes conflicting declarations when scoped @Provides functions returned the same type with different generic args.
  • Fixes default parameter handling with lambda or lazy values.
  • Fixes to kotlin native implementation that should make it more usable across threads.
    Note: the new memory model limitation is still present, but you can use https://github.com/touchlab/Stately to wrap
    the access when using the legacy memory model.
kotlin-inject - v0.4.0

Published by evant almost 3 years ago

[0.4.0] 2021-11-12

Changed

  • Updated kotlin to 1.5.31
  • Updated ksp to 1.5.31-1.0.1
  • Several improvements to code generation which often means less code is generated.

Added

  • Multiple rounds handling: This includes support for using types generated by other ksp processors. As a side effect
    there is better error reporting for unresolved types.

  • Support for multiplatform/native. Check out the sample project.

    Note: components are thread-safe, however you will run into issues actually using them from other threads unless you
    enable the new memory model.

  • Added support for default args when injecting. If the type is present in the graph, it'll be injected, otherwise the
    default will be used.

    @Inject class MyClass(val dep: Dep = Dep("default"))
    
    @Component abstract ComponentWithDep {
        abstract val myClass: MyClass
        @Provides fun dep(): Dep = Dep("injected")
    }
    @Component abstract ComponentWithoutDep {
        abstract val myClass: MyClass
    }
    
    ComponentWithDep::class.create().myClass.dep // Dep("injected")
    ComponentWithoutDep::class.create().myClass.dep // Dep("default")
    
kotlin-inject - v0.3.7-RC

Published by evant almost 3 years ago

[0.3.7-RC] 2021-10-29

Changed

  • Updated kotlin to 1.6.0-RC
  • Updated ksp to 1.6.0-RC-1.0.1-RC
  • Several improvements to code generation which often means less code is generated.

Added

  • Multiple rounds handling: This includes support for using types generated by other ksp processors. As a side effect
    there is better error reporting for unresolved types.
  • Support for multiplatform/native. Check out
    the sample project.
kotlin-inject - v0.3.6

Published by evant over 3 years ago

[0.3.6] - 2021-07-16

Changed

  • Updated kotlin to 1.5.20
  • Experimental kotlin js support

Fixed

  • Fix generated code for @Inject functions with a receiver
    ex: @Inject fun Foo.bar() = ...
  • Fix not using the typealias for function return types
kotlin-inject - v0.3.5

Published by evant over 3 years ago

[0.3.5] - 2021-06-02

Changed

  • Updated kotlin to 1.5.10
  • Updated ksp to beta01
kotlin-inject - v0.3.4

Published by evant over 3 years ago

[0.3.4] - 2021-05-30

Fixed

  • Fix metadata parsing issue with kapt on kotlin 1.5.0
  • Fix declaring function injection in another module in ksp

Changed

  • Updated kotlin to 1.5.0
  • Updated ksp to alpha10
kotlin-inject - v0.3.3

Published by evant over 3 years ago

[0.3.3] - 2021-04-20

Added

  • Allow cycles when there is delayed construction

    You can now break cycles by using Lazy or a function. For example,

    @Inject class Foo(bar: Bar)
    @Inject class Bar(foo: Foo)
    

    will fail with a cycle error, but you can fix it by doing

    @Inject class Foo(bar: Lazy<Bar>)
    @Inject class Bar(foo: Foo)
    

    or

    @Inject class Foo(bar: () -> Bar)
    @Inject class Bar(foo: Foo)
    

    This uses lateinit under the hood. You will get a runtime exception if you try to use the dependency before
    construction completes.

  • Added option me.tatarka.inject.dumpGraph to print the dependency graph while building. This can be useful for
    debugging issues.

  • Allow type-alias usage with @IntoMap.

    You can now do

    typealias Entry = Pair<String, MyValue>
    
    @Component {
        @Provides @IntoMap
        fun entry1(): Entry = "1" to MyValue(1)
        @Provides @IntoMap
        fun entry2(): Entry = "2" to MyValue(2)
    }
    

Changed

  • Code-gen optimization to reduce code size

  • ksp performance improvements

  • Made handling of nullable and platform types consistent on the different backends.

    It is now an error to return a platform type from a @Provides methods, you must declare the return type explicitly.

Fixed

  • Fix using @Qualifier on scoped dependencies
  • Fix declaring components as an inner class
  • Fix annotating java class constructors with @Inject
  • Fix @Inject on a companion object
kotlin-inject - v0.3.2

Published by evant over 3 years ago

[0.3.2] - 2021-04-05

Changed

kotlin-inject - v0.3.1

Published by evant over 3 years ago

[0.3.1] - 2021-02-25

Changed

kotlin-inject - v0.3.0

Published by evant almost 4 years ago

[0.3.0] - 2021-01-14

Changed

  • Updated ksp to 1.4.20-dev-experimental-20210111.

    Key changes:

    • You no longer have to define resolutionStrategy in your settings.gradle.
    • The plugin id has changed from symbol-processing to com.google.devtools.ksp.
  • Minimum supported kotlin version is now 1.4.20

Added

  • Support injecting suspend functions

    You can now define suspend component and provides methods

    @Component abstract class MyComponent {
      abstract val foo: suspend () -> IFoo
    
      val providesFoo: suspend () -> IFoo
          @Provides get() = { Foo() }
    }
    
  • Support default args in component constructors

    If you define any default args, you will get an overload create function that provides default values. Due to
    processor limitations, you only get a single overload (i.e. you cannot pass defaults from some args but not other).
    This can be useful for more conveniently defining parent components.

    @Component abstract class MyComponent(@Component val parent: ParentComponent = ParentComponent()) {
      ...
    }
    val component = MyComponent::class.create()
    
  • Support annotating constructors with @Inject

    Sometimes you don't want to use the primary constructor to construct an object. You can now annotate a more specific
    constructor instead.

    class MyClass {
      @Inject constructor(arg: String) // use this one for injection
      constructor(arg: Int)
    }
    
  • Support injecting objects

    While you can use an object directly, it may be useful to inject it so that you can switch it to an instance at a
    later point without updating the consuming code.

    @Inject object Foo { ... }
    @Inject MyClass(dep: Foo) { ... }
    

Fixed

  • Respect component's class visibility
  • Fix generating incorrect code for fun providers
kotlin-inject -

Published by evant almost 4 years ago

[0.2.0] - 2020-09-28

Changed

  • Migrate ksp
  • Improve kapt error messaging
  • Build performance improvements

Added

  • Allow annotating interfaces with @Component
  • Support javax.inject.Qualifer

Fixed

  • Fixed companion generation (me.tatarka.inject.generateCompanionExtensions=true) for ksp
  • Throw error when parent component is missing val instead of generating incorrect code.
kotlin-inject -

Published by evant about 4 years ago

Initial Release

Package Rankings
Top 17.02% on Repo1.maven.org
Badges
Extracted from project README
CircleCI Maven Central Sonatype Snapshot