2015-10-14 17 views
16

Il Kotlin reference dice che posso creare un singleton utilizzando l'oggetto parola chiave in questo modo:Singleton con argomento a Kotlin

object DataProviderManager { 
    fun registerDataProvider(provider: DataProvider) { 
    // 
    } 
} 

Tuttavia, vorrei passare un argomento a quell'oggetto. Ad esempio un ApplicationContext in un progetto Android.

C'è un modo per farlo?

risposta

10

Poiché gli oggetti non hanno costruttori, ho eseguito quanto segue per iniettare i valori in una configurazione iniziale. Puoi chiamare la funzione come vuoi e può essere richiamata in qualsiasi momento per modificare il valore (o ricostruire il singleton in base alle tue esigenze).

object Singleton { 
    private var myData: String = "" 

    fun init(data: String) { 
     myData = data 
    } 

    fun singletonDemo() { 
     System.out.println("Singleton Data: ${myData}") 
    } 
} 
1

Ci sono anche due nativi librerie iniezione Kotlin che sono abbastanza facile da usare, e hanno altre forme di single, tra cui per thread, chiave di base, ecc Non sono sicuro se è nel contesto della tua domanda, ma qui ci sono link ad entrambi:

Tipicamente in Android le persone utilizzano una libreria come questa, o Dagger, per eseguire la parametrizzazione dei singleton, per il loro scope, ecc.

3

Kotlin ha una funzionalità chiamata Operator overloading, che consente di passare argomenti direttamente a un oggetto.

object DataProviderManager { 
    fun registerDataProvider(provider: String) { 
     // 
    } 

    operator fun invoke(context: ApplicationContext): DataProviderManager { 
     //... 
     return this 
    } 
} 

//... 
val myManager: DataProviderManager = DataProviderManager(someContext) 
+0

Questo equivale alla soluzione di Jeremy, ma con una sintassi diversa. Il singleton è ancora creato senza argomenti. – jakk

+0

Se vuoi che funzioni come un costruttore, puoi semplicemente restituire "questo". Ho aggiornato la risposta dimostrando che. – breandan

+1

Ok, ma cosa ti impedisce di usare l'oggetto senza mai chiamare il metodo 'invoke'? – jakk