Contents

simonnickel/snap-dependencies

> This package is part of the [SNAP](https://github.com/simonnickel/snap) suite.

Demo project

The demo project contains an example setup of Dependencies.

<img src="/screenshot.png" height="400">

How to use

Register your Dependencies by extending Dependencies:

extension Dependencies {
	
	var service: Service { Service() }
	
	var serviceSwitched: Service {
		switch Dependencies.context {
			case .preview: Service(context: "Preview")
			case .test: Service(context: "Test")
			default: Service()
		}
	}
	
}

Inject Dependencies in your code:

@Observable class DataSource {

	@ObservationIgnored
	@Dependency(\.service) var service
	...
	
	func doingSomething() {
		@Dependency(\.service) var service
		...
	}
}

Override registration in Previews:

#Preview {
	Dependencies.override(\.service) { ServicePreview() }
	...
}

Override registration in Tests:

@Suite
@MainActor
struct MyAppTests {
	
	init() {
		Dependencies.reset()
	}
	
	@Test func someFeature() async throws {
		Dependencies.override(\.service) { ServiceTest() }
		...
	}
	
}

Forwarding

Forwarding is an optional feature. It allows to define and use a KeyPath in a package, but provide the actual dependency in the consuming package.

Define the KeyPath in a package:

public extension Dependencies {

	var service: Service { Dependencies.forwarding(for: \.service) }

}

Implement the protocol DependencyForwardingFactory in your app and create an instance of the expected type:

extension Dependencies: @retroactive DependencyForwardingFactory {
	
	public func create<Dependency>(for keyPath: KeyPath<Dependencies, Dependency>) -> Dependency? {
		switch keyPath {
				
			case \.service: Service() as? Dependency
				
			default: nil

		}
	}
	
}

Package Metadata

Repository: simonnickel/snap-dependencies

Default branch: main

README: README.md