Skip to content

Provider

apleshkov edited this page Aug 1, 2018 · 4 revisions

Providers are very powerful when it comes to:

  • making dependencies abstract with some additional logic binders don't support
  • using needed third-party types you're not able to annotate
  • ...

Every provider is a service with one and only one method which:

  • has the @saber.provider annotation
  • has a return type to determine an actual dependency

Abstract

protocol Logging {
    
    func log(_ message: String)
}

class ConsoleLogger: Logging {
    
    func log(_ message: String) {
        print(message)
    }
}

class FileLogger: Logging {
    
    func log(_ message: String) {
        // ...
    }
}

// @saber.scope(App)
// @saber.cached
class LoggerProvider {
    
    private let logger: Logging
    
    init() {
        #if USE_CONSOLE_LOGGER
        logger = ConsoleLogger()
        #else
        logger = FileLogger()
        #endif
    }
    
    // @saber.provider
    func provide() -> Logging {
        return logger
    }
}

// @saber.scope(App)
class NetworkManager {
    
    // @saber.inject
    init(logger: Logging) {
        // ...
    }
}

Third-party

import PerfectMySQL

// @saber.scope(App)
// @saber.cached
class DatabaseProvider {
    
    private let mysql = MySQL()

    deinit {
        mysql.close()
    }

    init() {
        // Connecting...
    }

    // @saber.provider
    func provide() -> MySQL {
        return mysql
    }
}

Now use it as a dependency:

// @saber.scope(App)
// @saber.cached
class Storage {

    private let db: MySQL

    // @saber.inject
    init(db: MySQL) {
        self.db = db
    }
}
Clone this wiki locally