<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pedro Francisco de Sousa Neto</title>
    <description>The latest articles on DEV Community by Pedro Francisco de Sousa Neto (@pedrofsn).</description>
    <link>https://dev.to/pedrofsn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F529886%2F72b402d9-6f34-4ff3-8acb-53b2a8ee7e9b.png</url>
      <title>DEV Community: Pedro Francisco de Sousa Neto</title>
      <link>https://dev.to/pedrofsn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pedrofsn"/>
    <language>en</language>
    <item>
      <title>Conhecendo o Koin Annotations</title>
      <dc:creator>Pedro Francisco de Sousa Neto</dc:creator>
      <pubDate>Mon, 26 Feb 2024 13:10:59 +0000</pubDate>
      <link>https://dev.to/pedrofsn/conhecendo-o-koin-annotations-5d45</link>
      <guid>https://dev.to/pedrofsn/conhecendo-o-koin-annotations-5d45</guid>
      <description>&lt;h2&gt;
  
  
  Declarando dependências com Koin
&lt;/h2&gt;

&lt;p&gt;Através deste artigo você irá &lt;strong&gt;aprender&lt;/strong&gt; todas as formas de &lt;strong&gt;como realizar as declarações de dependências utilizando&lt;/strong&gt; o Koin - Koin DSL, Constructor DSL e finalmente o poderosíssimo &lt;strong&gt;Koin Annotations&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Koin DSL
&lt;/h3&gt;

&lt;p&gt;Desta forma declaramos o módulo Koin e inicializamos os construtores de maneira explícita, invocando o famoso &lt;code&gt;get()&lt;/code&gt; do Koin.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

class ClassA()
class ClassB(val a: ClassA)

val myModule = module {
    single { ClassA() }
    single { ClassB(a = get()) }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Constructor DSL
&lt;/h3&gt;

&lt;p&gt;Desta maneira o trabalho fica bem mais simples, pois não precisamos declarar de maneira explícita os parâmetros dos construtores.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

class ClassA()
class ClassB(val a: ClassA)

val myModule = module {
    singleOf(::ClassA)
    singleOf(::ClassB)
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Anotações
&lt;/h3&gt;

&lt;p&gt;E por fim, chegamos onde a mágica realmente acontece, pois podemos deixar de usar (ou não) a declaração de dependências num módulo Koin. Apenas utilizando as anotações nas classes das nossas dependências.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Single
class ClassA()

@Factory
class ClassB(val a: ClassA)

@KoinViewModel
class MyViewModel(b: ClassB): ViewModel()

@KoinWorker
class UploadFiles: WorkManager()


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Também é possível utilizar escopos e propriedades nas suas anotações, para mais detalhes consulte o guia do Koin Annotations &lt;a href="https://insert-koin.io/files/Koin-CheatSheet-2023.pdf" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Koin Annotations
&lt;/h2&gt;

&lt;p&gt;Até aqui acredito que já tenham percebido o quão poderoso é o Koin Annotations, e também o quão é parecido com outros &lt;em&gt;players&lt;/em&gt; do mercado, como o Dagger e o Hilt, certo?&lt;/p&gt;

&lt;p&gt;O &lt;em&gt;Koin Annotations&lt;/em&gt; funciona de maneira adicional aos projetos Kotlin que fazem o uso do Koin. Sendo integrável a projetos já existentes e também há novos projetos.&lt;/p&gt;

&lt;p&gt;Com a adoção do &lt;em&gt;Koin Annotations&lt;/em&gt; além de deixarmos o código escrito de uma maneira mais simples por anotações, ainda podemos fazer o uso de um recurso que costuma ser o motivo de muitas queixas contrárias ao uso do Koin, que é a verificação das dependências em tempo de compilação!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7l0xvr4imvxype1j94b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7l0xvr4imvxype1j94b.gif" alt="brain explosion meme animated gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compile Safety
&lt;/h2&gt;

&lt;p&gt;Com este recurso é possível validar todas as dependências em tempo de compilação tal qual o Hilt ou o Dagger faz. Apenas adicionando uma linha de código &lt;code&gt;ksp { arg("KOIN_CONFIG_CHECK", "true") }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Segundo a &lt;a href="https://www.kotzilla.io/" rel="noopener noreferrer"&gt;Kotzilla&lt;/a&gt;, empresa responsável por manter e distribuir o Koin, o tempo de compilação do &lt;em&gt;Koin Annotations&lt;/em&gt; é &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7160561406608605185/" rel="noopener noreferrer"&gt;75% mais rápido que o Dagger&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;em&gt;compile safety&lt;/em&gt; é um recurso &lt;strong&gt;ainda experimental&lt;/strong&gt;. Mas tenho aplicado-o num projeto de Server-Driven UI, no core do SDK_ a ser utilizado pelo &lt;em&gt;client-side&lt;/em&gt; android. Em mais de 1 mês de uso não tive problemas. &lt;/p&gt;

&lt;p&gt;É válido lembrar que o &lt;em&gt;compile safety&lt;/em&gt; é configurável então pode ser habilitado ou desabilitado a qualquer momento via arquivo gradle - o padrão é &lt;code&gt;false&lt;/code&gt;/desabilitado. &lt;/p&gt;

&lt;p&gt;Um ponto negativo, na minha opinião, é que o &lt;em&gt;compile safety&lt;/em&gt; não consegue enxergar as dependências declaradas em Koin DSL ou Constructor DSL.&lt;/p&gt;

&lt;p&gt;Abaixo temos um exemplo de erro ao tentar compilar um projeto contendo o recurso habilitado e uma dependência não &lt;del&gt;mapeada&lt;/del&gt; anotada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlvokd0o1o8y4ltzk8rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlvokd0o1o8y4ltzk8rq.png" alt="ksp-classb-missing-classa"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting:&lt;/strong&gt; O Koin não conseguiu satisfazer a dependência de &lt;code&gt;ClassA&lt;/code&gt; que era esperada no construtor de &lt;code&gt;ClassB&lt;/code&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Mas e os meus módulos?
&lt;/h2&gt;

&lt;p&gt;Por baixo do capô, o &lt;em&gt;Koin Annotations&lt;/em&gt; gerará um módulo que contém todas as dependências mapeadas. E para usar este módulo no seu tradicional &lt;code&gt;startKoin&lt;/code&gt; é muito simples, exemplo: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// Usar o módulo default gerado pelo Koin Annotations
import org.koin.ksp.generated.*

fun main() {
    startKoin { defaultModule() }
}

// Cenário com N módulos
fun main() {
    startKoin { modules(defaultModule, moduleA, moduleB, existingModule) }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Mas e a organização?
&lt;/h3&gt;

&lt;p&gt;Se você pensar num projeto muito grande, com várias dependências, o módulo default pode não soar como algo muito organizado.&lt;br&gt;
Para evitar que o &lt;em&gt;Koin Annotations&lt;/em&gt; gere este módulo basta desativar esta configuração padrão com &lt;code&gt;ksp { arg("KOIN_DEFAULT_MODULE", "false") }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E neste caso, deveremos passar a declarar o uso dos módulos gerados pelas anotações. Veja os exemplos abaixo.&lt;/p&gt;

&lt;p&gt;Módulo Koin com Koin Annotations:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Module
class MyGiantModule


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Utilizando o módulo gerado:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import org.koin.ksp.generated.*

fun main() {
    startKoin { modules(MyGiantModule().module) }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Como declarar as dependências de cada @Module?
&lt;/h3&gt;

&lt;p&gt;Agora vejamos mais uma anotação para o seu módulo, a &lt;code&gt;@ComponentScan&lt;/code&gt;. Ela fará com que todas as dependências declaradas no mesmo package e subpackages sejam mapeadas para o seu &lt;code&gt;@Module&lt;/code&gt;. Veja o exemplo a seguir:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Module
class MyModule


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Você também pode especificar o package que deverá ser observado para mapear as dependências. Da seguinte maneira:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Module
@ComponentScan("com.my.app")
class MyModule


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ainda é possível declarar dependências diretas no seu módulo anotado utilizando funções do Kotlin.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Module
@ComponentScan("com.my.app")
class MyModule {

    @Factory
    fun service(retrofit: Retrofit): ServiceAPI {
        return retrofit.create(ServiceAPI::class.java)
    }

}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Mas e se eu precisar de mais um @Module?
&lt;/h3&gt;

&lt;p&gt;A inclusão de módulos funciona com as anotações, da seguinte forma:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Module
class ModuleA

@Module(includes = [ModuleA::class])
class ModuleB


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E neste caso poderíamos utilizar da seguinte forma:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;import org.koin.ksp.generated.*&lt;/p&gt;

&lt;p&gt;fun main() {&lt;br&gt;
    startKoin {&lt;br&gt;
        modules(&lt;br&gt;
          // Irá carregar o ModuleB e o ModuleA&lt;br&gt;
          ModuleB().module&lt;br&gt;
        )&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusão&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;em&gt;Koin Annotations&lt;/em&gt; pode ser utilizados em novos projetos e em projetos já existentes. Além disto ele traz uma maneira bastante idiomática para se trabalhar com injeção de dependência em Kotlin. &lt;/p&gt;

&lt;p&gt;Acredito que este era o último passo que faltava para o Koin fazer brilhar os olhos de qualquer desenvolvedor Kotlin! &lt;br&gt;
E só mais uma coisa, o &lt;em&gt;Koin Annotations&lt;/em&gt; não é específico da plataforma Android, ele também &lt;a href="https://insert-koin.io/docs/reference/koin-annotations/start#kotlin-kmp-setup" rel="noopener noreferrer"&gt;funciona em projetos multiplataformas&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Próximos Passos
&lt;/h2&gt;

&lt;p&gt;Ainda há mais temas para serem cobertos em relação ao &lt;em&gt;Koin Annotations&lt;/em&gt;, por exemplo: especificar o binding de uma dependência, injetar um parâmetro, injetar uma dependência &lt;code&gt;lazy&lt;/code&gt;, obter uma lista de dependências de um mesmo tipo, etc.&lt;br&gt;
Para estes e outros temas consulte a &lt;a href="https://insert-koin.io/docs/reference/koin-annotations/start" rel="noopener noreferrer"&gt;documentação oficial do Koin Annotations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Em breve farei um novo artigo demostrando como adicionar o &lt;em&gt;Koin Annotations&lt;/em&gt; em apenas um módulo de um projeto. Desta maneira, demonstrando a flexibilidade que temos para poder evoluir um projeto que já utilize o Koin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Créditos da imagem da capa
&lt;/h2&gt;

&lt;p&gt;Foto de &lt;a href="https://unsplash.com/pt-br/@pawel_czerwinski?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Pawel Czerwinski&lt;/a&gt; na &lt;a href="https://unsplash.com/pt-br/fotografias/um-close-up-de-uma-parede-de-azulejo-de-marmore-rosa-CEr4ljpMSh4?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>koin</category>
      <category>kotlin</category>
      <category>annotations</category>
      <category>multiplatform</category>
    </item>
  </channel>
</rss>
