

A modern approach to Container-Based Dependency Injection for Swift and SwiftUI.
Factory Version 3.2.2
Factory is strongly influenced by SwiftUI, and in my opinion is highly suited for that environment. Factory is...
- Adaptable: Factory doesn't tie you down to a single dependency injection strategy or technique.
- Powerful: Factory supports containers, scopes, passed parameters, contexts, decorators, unit tests, SwiftUI Previews, and much, much more.
- Performant: Little to no setup time is needed for the vast majority of your services, resolutions are extremely fast, and no compile-time scripts or build phases are needed.
- Safe: Factory is compile-time safe; a factory for a given type must exist or the code simply will not compile.
- Concise: Defining a registration usually takes just a single line of code. Same for resolution.
- Flexible: Working with UIKIt or SwiftUI? iOS or macOS? Using MVVM? MVP? Clean? VIPER? No problem. Factory works with all of these and more.
- Documented: Factory has extensive DocC documentation and examples covering its classes, methods, and use cases.
- Lightweight: With all of that Factory is slim and trim, under 1,000 lines of executable code.
- Tested: Unit tests with 100% code coverage helps ensure correct operation of registrations, resolutions, and scopes.
- Testable: Factory ensures your application's views and services are easily previewable and testable.
- Free: Factory is free and open source under the MIT License.
Sound too good to be true? Let's take a look.
A Simple Factory
Most container-based dependency injection systems require you to define in some way that a given service type is available for injection, and many require some sort of factory or mechanism that will provide a new instance of the service when needed.
Factory is no exception. Here's a simple dependency registration that returns a service that conforms to MyServiceType.
extension Container {
var myService: Factory<MyServiceType> {
self { MyService() }
}
}
Unlike frameworks that require registering every single type up front, or SwiftUI, where defining a new environment variable requires creating a new EnvironmentKey and adding additional getters and setters, here we simply add a new Factory computed variable to the default container. When it's called our Factory is created, its closure is evaluated, and we get an instance of our dependency when we need it.
That self { ... } syntax is sugared shorthand that replaces the more explicit Factory(self) { ... } format. Both are equivalent.
Resolution
Injecting an instance of our service is equally straightforward. Here's just one of the many ways Factory can be used.
class ContentRepository {
@Injected(\.myService) private var myService
...
}
This particular class uses one of Factory's @Injected property wrappers to request the desired dependency. Similar to @Environment in SwiftUI, we provide the property wrapper with a keyPath to a factory of the desired type and it resolves that type the moment ContentRepository is created.
And that's the core mechanism. In order to use the property wrapper you must define a factory within the specified container. That factory must return the desired type when asked. Fail to do either one and the code will simply not compile. As such, Factory is compile-time safe.
By the way, if you're concerned about building Factory's on the fly, don't be. Like SwiftUI Views, Factory structs and modifiers are lightweight and transitory value types. They're created inside computed variables only when they're needed and then immediately discarded once their purpose has been served.
For more examples of Factory definitions that define scopes, use constructor injection, and do parameter passing, see the Registrations page.
Other Factory Resolution Methods
We started by demonstrating the @Injected property wrapper, but it's also possible to bypass the property wrapper and talk to the factory yourself.