import Foundation
/*
依赖注入好处
1 解耦
对象不再负责自己创建依赖,而是由外部提供,类之间依赖是接口而不是具体实现
好处:更易替换实现(如网络层、数据库、日志等)
• 更容易进行模块化开
2 更容易测试
你可以轻松传入 Mock 或 Stub 对象来测试,而不需要依赖真实的服务。
3 提高复用性
相同类可以在不同场景下配合不同的依赖使用
4 代码更清晰,职责更明确
每个类仅关注自身逻辑,而不是负责构造其它对象,遵循单一职责原则
5 更容易扩展
当你要新增新的依赖实现(例如换一套网络框架、替换数据库),只需在注册时更换绑定即可,无需修改使用者代码
6 支持依赖生命周期管理
使用依赖注入框架( Swinject、Resolver),可以统一管理依赖的作用域(如单例、临时对象等)。
7 适合一些比较大的项目
在大型项目中,依赖关系复杂,手动管理困难。使用 DI 可以统一管理和清晰可视化依赖图(特别适合 VIPER / MVVM / Clean Architecture)
*/
protocol USERService {
func getUserName() -> String
}
class DefaultUser: USERService {
func getUserName() -> String {
return "Default"
}
}
class ProfileViewModel{
private let userService: USERService
init(userService: USERService) {
self.userService = userService
}
func showname(){
print("\(userService.getUserName())")
}
}
let viewmodel = ProfileViewModel(userService: DefaultUser())
import Swinject
let container = Container()
// 注册服务到容器
func swinjecttest1() {
container.register(USERService.self) { _ in
DefaultUser()
}
}
// 注入依赖
func resolveDependence() {
if let service = container.resolve(USERService.self) {
let viewmodel = ProfileViewModel(userService: service)
viewmodel.showname()
}
}
class AnalyticsManager {
let userService: USERService
init(userService: USERService) {
self.userService = userService
}
}
// 注册带依赖的对象
func registDependence() {
container.register(AnalyticsManager.self) { resolver in
let userService = resolver.resolve(USERService.self)
return AnalyticsManager(userService: userService!)
}.inObjectScope(.container) /*
// 默认 transient,每次都新建
// .container 保持整个容器周期内为同一实例
// .graph 同一解析图中复用
*/
}
/// 实际项目中应用
class AppContianer {
let contianer = Container()
init() {
registServices()
}
func registServices() {
container.register(USERService.self) { _ in
DefaultUser()
}
contianer.register(ProfileViewModel.self) { resolver in
ProfileViewModel(userService: resolver.resolve(USERService.self)!)
}
}
}
// app启动时候注入
func appdidFinishedLaunching() {
let di = AppContianer()
let viewmodel = di.contianer.resolve(ProfileViewModel.self)
}
/// 也可以将方法封装成一层范型接口使用
let bcontainer = Container()
func regist<T>(type: T.Type, instance: T) {
container.register(type) { _ in
instance
}
}
func resolve<T>(type: T.Type) -> T? {
container.resolve(type)
}
swift 使用 Swinject 依赖注入
最新推荐文章于 2025-06-30 23:50:29 发布