SwiftInjection 0.8

SwiftInjection 0.8

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布日期最后发布日期2017年10月
SwiftSwift版本3.0
SPM支持SPM

Aryan Ghassemi维护。



  • 作者
  • Aryan Ghassemi

SwiftInjection

Build Status

Swift的依赖项容器

设置依赖项

模块文件是你定义依赖项的地方。目标是抽象出这个文件中的所有依赖项。应该只有项目中的模块类知道具体实现,而你的应用中的其余类应通过接口使用这些实现。

你可以有多个模块类来组织你的依赖项

public class AppModule: DIModule {
    
    public func load(container: DIContainer) {
        container.bind(type: URLSession.self) { URLSession.shared() }
        container.bind(type: HttpService.self) { HttpClient(baseUrl: "https://api.github.com", urlSession: container.resolve(type: URLSession.self)) }
        container.bind(type: GithubService.self) { GithubHttpClient(httpService: container.resolve(type: HttpService.self)) }
        container.bind(type: UserDefaults.self, asSingleton: false) { UserDefaults.standard() }
        container.bind(type: AnalyticsTracker.self, named: GoogleAnalyticsTracker.analyticsIdentifier()) { GoogleAnalyticsTracker() }
        container.bind(type: AnalyticsTracker.self, named: AmplitudeAnalyticsTracker.analyticsIdentifier()) { AmplitudeAnalyticsTracker() }
    }
    
}

class AppDelegate: UIResponder, UIApplicationDelegate {
    override init() {
        super.init()
        DIContainer.instance.addModule(AppModule())
    }
}

绑定内部类

避免直接使用单例,以提高代码的可测试性

container.bind(type: URLSession.self) { URLSession.shared() }

将类绑定为单例

不要在你的类中添加单例逻辑,只需将它们绑定为单例
注意:结构体与单例模式不兼容

// Bind class as singleton
bind(Session.self, asSingleton: true) { Session() }

// Bind protocol to an implementation as singleton
bind(AnalyticsTracker.self, asSingleton: true) { GoogleAnalyticsTracker() }

绑定名称实例

在存在多个单一协议实现的情况下,您可以使用名称绑定来检索正确的实例

bind(AnalyticsTracker.self, named: "Google") { GoogleAnalyticsTraker() }
bind(AnalyticsTracker.self, named: "Amplitude") { AmplitudeAnalyticsTracker() }

// Inject expected instance
let googleAnalyticsTracker: AnalyticsTracker = inject(named: "Google")
let amplitudeAnalyticsTracker: AnalyticsTracker = inject(named: "Amplitude")

// Get all implementations for a given protocol (great for chain of responssibilities)
let trackers: [AnalyticsTracker] = injectAll()

属性注入

仅对根级别使用属性注入,对于viewController以下的任何内容都使用构造器注入

class ViewController: UIViewController {
    let githubService: GithubService = inject() // Injects the implementation defined in module
  let session = inject(Session.self) // injects the singleton instance
  let analyticTrackers: [AnalyticsTracker] = injectAll() // Injects all implemetations of AnalyticsTracker
}

构造器注入

简单地将依赖项通过初始化程序传递,并在模块文件中定义绑定

protocol GithubService { }

protocol HttpService { }

class GithubHttpClient: GithubService {
    let httpService: HttpService
    // Constructor injection
  init(httpService: HttpService) {
        self.httpService = httpService
    }
}

class AppModule: DIModule {
    func load(container: DIContainer) {
        container.bind(type: URLSession.self) { URLSession.shared() }
        container.bind(type: HttpService.self) { HttpClient(baseUrl: "https://api.github.com", urlSession: container.resolve(type: URLSession.self)) }
        container.bind(type: GithubService.self) { GithubHttpClient(httpService: container.resolve(type: HttpService.self)) }
    }
}

class ViewController: UIViewController {
    // Property Injection
  // This will return an instance of GithubHttpClient with all depndencies as defined in module
  let githubService: GithubService = inject()
}