Service Locator 是一种设计模式,用于将获取对象的方式与实现对象的具体类解耦。 它的实现方式是将对象创建集中到一个位置,称为服务定位器。
这个小项目受到 RouterService 和 Swinject 的启发
模块对相关的服务注册进行分组。 它们重写 build() 方法来定义服务如何向定位器注册。
class MyModule: ServiceLocatorModule {
override func build() {
// singletons
single(ConfigProviderProtocol.self) {
ConfigProvider()
}
// get dependencies with resolve
single(URLFactory.self) {
URLFactory(remoteConfigProvider: self.resolve())
}
// factory
factory(AppLinkFactory.self) {
let settingsManager: SettingsManager = self.resolve()
return AppLinkFactory(descriptionFactory: settingsManager)
}
}
}
提示:定义一个应用程序范围内的模块,其中包含其他模块。
class AppModule: ServiceLocatorModule {
override func build() {
module { MyModule() }
}
}
lazy var myServiceLocator = startServiceLocator {
AppModule()
}
myServiceLocator.build()
使用 @Inject 在类或结构体中检索依赖。 属性包装器自动从服务定位器解析依赖
class MyCass {
@Inject(myServiceLocator) public var contactSheet: ContactSheet
}
对于在函数或方法中注入依赖,请在局部变量声明之前使用 @Inject
func doSomething() {
@Inject(myServiceLocator) var contactSheet: ContactSheet
// Use contactSheet here
}
如果您不喜欢使用属性包装器,请使用服务定位器的 resolve 方法直接解析依赖
let configProvider : ConfigProvider = serviceLocator.resolve()
您可以将 ServiceLocator 重置为其初始状态,这在测试场景中非常有用
// Reset the entire service locator
resetServiceLocator(myServiceLocator)
// Or, if you have direct access to the ServiceLocator instance:
myServiceLocator.reset()
如果您有特定需求或想简化特定范围的用法(例如本例中的插件),请创建定制的属性包装器
@propertyWrapper
internal final class PluginInject<T>: Dependency<T> {
public var wrappedValue: T {
resolvedWrappedValue()
}
public init() {
super.init(MyPlugin.shared.myServiceLocator)
}
}
用法
class MyClass {
@PluginInject var contactSheet: ContactSheet
}
func doSomething() {
@PluginInject var contactSheet: ContactSheet
}
您可以为 ServiceLocator 启用日志记录,以帮助进行调试
ServiceLocator.enableLogging = true
将依赖项添加到您的 Package.swift
products: [
...
]
dependencies: [
.package(url: "https://github.com/kibotu/ServiceLocator", from: "1.0.2"),
],
targets: [
...
]
欢迎贡献!
Copyright 2024 Jan Rabe & CHECK24 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://apache.ac.cn/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.