# Configuração de Injeção de Dependência

Este guia explica como instanciar e gerenciar os repositórios fornecidos pela `redsys-tpv-business-lib`. Embora você possa instanciar repositórios manualmente, a biblioteca foi projetada para funcionar perfeitamente com frameworks de Injeção de Dependência (DI), como o Dagger Hilt.

O núcleo do processo de instanciação é a classe auxiliar `RepositoryProvider`, que fornece as implementações específicas para todos os recursos da biblioteca.

## Opção 1: Usando Dagger Hilt (Recomendado)

Se sua aplicação utiliza Hilt, você deve fornecer os repositórios como **Singletons**. Isso garante que você tenha uma única instância compartilhada de cada repositório durante todo o ciclo de vida da sua aplicação.

### 1. Criar um Módulo Hilt

Crie um novo arquivo de módulo (ex: `AppModule.kt`) anotado com `@Module` e `@InstallIn(SingletonComponent::class)`.

### 2. Fornecer os Repositórios

Copie o código a seguir para fornecer o `RepositoryProvider` e todos os repositórios de recursos disponíveis.

<Callout type="note">

O `RepositoryProvider` requer o Contexto da Aplicação e uma flag `DEBUG` (para habilitar o log interno com Timber).

</Callout>

```kotlin
@Module
@InstallIn(SingletonComponent::class)
class AppModule {

    @Provides
    @Singleton
    fun provideRepositoryProvider(@ApplicationContext context: Context): RepositoryProvider {
        // Pass BuildConfig.DEBUG to enable internal Smart SDK logging
        return RepositoryProvider(context, BuildConfig.DEBUG)
    }

    // --- Core Payments & Transactions ---

    @Provides
    @Singleton
    fun provideInitializationRepository(provider: RepositoryProvider): InitializationRepository =
        provider.initializationRepository

    @Provides
    @Singleton
    fun providePaymentRepository(provider: RepositoryProvider): PaymentRepository =
        provider.paymentRepository

    @Provides
    @Singleton
    fun provideTransactionRepository(provider: RepositoryProvider): TransactionRepository =
        provider.transactionRepository

    @Provides
    @Singleton
    fun providePreauthorizationRepository(provider: RepositoryProvider): PreauthorizationRepository =
        provider.preauthorizationRepository

    @Provides
    @Singleton
    fun provideRefundRepository(provider: RepositoryProvider): RefundRepository =
        provider.refundRepository

    // --- Management & Peripherals ---

    @Provides
    @Singleton
    fun provideSessionRepository(provider: RepositoryProvider): SessionRepository =
        provider.sessionRepository

    @Provides
    @Singleton
    fun provideShiftRepository(provider: RepositoryProvider): ShiftRepository =
        provider.shiftRepository

    @Provides
    @Singleton
    fun provideTotalsRepository(provider: RepositoryProvider): TotalsRepository =
        provider.totalsRepository

    @Provides
    @Singleton
    fun providePrinterRepository(provider: RepositoryProvider): PrinterRepository =
        provider.printerRepository

    @Provides
    @Singleton
    fun provideSettingsRepository(provider: RepositoryProvider): SettingsRepository =
        provider.settingsRepository

    // --- Alternative Payment Methods (APMs) & Digital Services ---

    @Provides
    @Singleton
    fun provideBizumRepository(provider: RepositoryProvider): BizumRepository =
        provider.bizumRepository

    @Provides
    @Singleton
    fun provideAlipayRepository(provider: RepositoryProvider): AlipayRepository =
        provider.alipayRepository

    @Provides
    @Singleton
    fun provideWeChatRepository(provider: RepositoryProvider): WeChatRepository =
        provider.weChatRepository

    @Provides
    @Singleton
    fun provideTicketDigitalRepository(provider: RepositoryProvider): TicketDigitalRepository =
        provider.ticketDigitalRepository

    @Provides
    @Singleton
    fun provideAuthRepository(provider: RepositoryProvider): AuthRepository =
        provider.authRepository
}
```

Agora você pode injetar essas interfaces diretamente em seus ViewModels ou UseCases.

**Exemplo de Uso:**

```kotlin
@HiltViewModel
class PaymentViewModel @Inject constructor(
    private val paymentRepository: PaymentRepository
) : ViewModel() {
    // ...
}
```

## Opção 2: Injeção Manual

Se o seu projeto não utiliza um framework de Injeção de Dependência, você pode instanciar os repositórios manualmente utilizando o `RepositoryProvider` ou os métodos estáticos `newInstance` nas classes de implementação.

### Usando RepositoryProvider

Você pode criar uma única instância do `RepositoryProvider` (ex: em sua classe `Application`) e acessar os repositórios através de suas propriedades.

```kotlin
// In your Application class or a Singleton container
val provider = RepositoryProvider(context, BuildConfig.DEBUG)

val paymentRepo = provider.paymentRepository
val printerRepo = provider.printerRepository
```

### Instanciação Direta

Alternativamente, você pode criar instâncias diretamente usando o método estático `newInstance` fornecido pelas classes de implementação (prefixadas com `Psa` para Payment Service Adapter).

```kotlin
// Example: Creating a TransactionRepository manually
val transactionRepo = PsaTransactionRepository.newInstance(context)

// Example: Creating a PaymentRepository manually
val paymentRepo = PsaPaymentRepository.newInstance(context)
```

<Callout type="note">

Embora a instanciação manual funcione para testes simples, o uso de `RepositoryProvider` ou DI é recomendado para apps em produção para melhor gerenciar a memória e as dependências.

</Callout>

## Próximos Passos

Agora que seus repositórios estão prontos, você deve prosseguir para o passo mais crítico:

* [**Tratamento de Respostas e Erros**](/pt/get-smart/get-smart-sdk/core-concepts/handle-responses-and-errors): Aprenda como lidar com o wrapper `RepositoryResult` retornado por todos esses repositórios.