Member-only story
Featured
The Best API Change Is the One Nobody Notices
Scene-aware custom containers in Factory, and the design that let the existing API stay put…
Every library author eventually learns that new capability costs new API.
A new feature means a new parameter, a new generic, a new protocol requirement, and a migration guide for everyone who already depends on you. It’s practically a law of nature.
Sometimes.
In my last article I introduced scene-based injection for Factory’s default container. It left a gap, and closing that gap looked like it was going to break things. It didn’t, and the reason why is worth a look.
The Gap
Here’s what scenes gave us. Install a Container at the root of each window, publish it in the environment, and @InjectedObject and @InjectedObservable resolve from it instead of Container.shared.
@main
struct DemoApp: App {
var body: some Scene {
WindowGroup {
SceneRoot()
}
}
}
struct SceneRoot: View {
@State private var sceneContainer = Container()
var body: some View {
ContentView()
.withContainer(sceneContainer)
}
}
struct ContentView: View {
@InjectedObservable(\.contentViewModel) var model
var body: some…







