How to define dependencies that have other dependencies? #1713
-
Hey 👋 If you look at the code examples from the documentation you can only get an impression of how a single layer of dependencies can be implemented. If you take a look at the Isowords example project you can see another approach that could give you an idea of extension APIWrapper {
public static var live: Self {
let networkingService = NetworkingService() // Defining sub
return Self(
getObjects: {
let target = Target.someTarget
let data = try await networkingService.requestTarget(target: target)
let objects = ..... // convert data to Objects
return objects
}
)
}
} However, this approach has the disadvantage that the actual implementations extension APIWrapper {
public static func live(networkingService: NetworkingService = .live) -> Self {
return Self(
getObjects: {
let target = Target.someTarget
let data = try await networkingService.requestTarget(target: target)
let objects = ..... // convert data to Objects
return objects
}
)
}
} Now one would have the possibility to test the implementations of a dependency with mocked dependencies in the tests. final class APIWrapper_Tests: XCTestCase {
func testImplementation() async throws {
let wrapperWithMockedDependencies = APIWrapper.live(networkingService: .mocked)
let objects = await apiWithMockedDependencies.getObjects()
// do some assertions
}
} Unfortunately, I am not quite sure if this is the preferred way, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hey @iwt-sebastian-boldt ✌️, I think this example from isowords will answer your question let store = Store(
initialState: AppReducer.State(),
reducer: AppReducer().transformDependency(\.self) {
$0.audioPlayer = .liveValue
$0.database = .live(
path: FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
.first!
.appendingPathComponent("co.pointfree.Isowords")
.appendingPathComponent("Isowords.sqlite3")
)
$0.serverConfig = .live(apiClient: $0.apiClient, build: $0.build)
}
) or here's another approach import ComposableArchitecture
import Foundation
struct URLProvider {
var url: URL
}
struct ApiClient {
var tellMeURL: () -> URL
}
private enum ApiClientKey: DependencyKey {
static let liveValue = ApiClient(tellMeURL: {
@Dependency(\.urlProvider) var urlProvider
return urlProvider.url
})
}
private enum URLProviderKey: DependencyKey {
static let liveValue = URLProvider(url: URL(string: "some.com")!)
}
extension DependencyValues {
var urlProvider: URLProvider {
get { self[URLProviderKey.self] }
set { self[URLProviderKey.self] = newValue }
}
} |
Beta Was this translation helpful? Give feedback.
Hey @iwt-sebastian-boldt ✌️,
I think this example from isowords will answer your question
or here's another approach