[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7066":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":15,"stars7d":17,"stars30d":14,"stars90d":16,"forks30d":16,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":33,"lastSyncTime":34,"discoverSource":35},7066,"Factory","hmlongco\u002FFactory","hmlongco","A modern approach to Container-Based Dependency Injection for Swift and SwiftUI.","",null,"Swift",2857,182,29,1,0,4,28.79,"MIT License",false,"main",true,[24,25,26,27,28,29],"container","dependency-injection","ios","swift","swiftui","xcode","2026-06-12 02:01:34","[![](https:\u002F\u002Fimg.shields.io\u002Fendpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fhmlongco%2FFactory%2Fbadge%3Ftype%3Dswift-versions)](https:\u002F\u002Fswiftpackageindex.com\u002Fhmlongco\u002FFactory)\n[![](https:\u002F\u002Fimg.shields.io\u002Fendpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fhmlongco%2FFactory%2Fbadge%3Ftype%3Dplatforms)](https:\u002F\u002Fswiftpackageindex.com\u002Fhmlongco\u002FFactory)\n\n![](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FFactory\u002Fblob\u002Fmain\u002FLogo.png?raw=true)\n\nA modern approach to Container-Based Dependency Injection for Swift and SwiftUI.\n\n## Factory Version 3.0.2\n\nFactory is strongly influenced by SwiftUI, and in my opinion is highly suited for that environment. Factory is...\n\n- **Adaptable**: Factory doesn't tie you down to a single dependency injection strategy or technique.\n- **Powerful**: Factory supports containers, scopes, passed parameters, contexts, decorators, unit tests, SwiftUI Previews, and much, much more.\n- **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.\n- **Safe**: Factory is compile-time safe; a factory for a given type must exist or the code simply will not compile.\n- **Concise**: Defining a registration usually takes just a single line of code. Same for resolution.\n- **Flexible**: Working with UIKIt or SwiftUI? iOS or macOS? Using MVVM? MVP? Clean? VIPER? No problem. Factory works with all of these and more.\n- **Documented**: Factory has extensive DocC documentation and examples covering its classes, methods, and use cases.\n- **Lightweight**: With all of that Factory is slim and trim, under 1,000 lines of executable code.\n- **Tested**: Unit tests with 100% code coverage helps ensure correct operation of registrations, resolutions, and scopes.\n- **Testable**: Factory ensures your application's views and services are easily previewable and testable. \n- **Free**: Factory is free and open source under the MIT License.\n\nSound too good to be true? Let's take a look.\n  \n---\n\nBut before we do, I want to express my thanks to Mercedes-Benz, Süddeutsche Zeitung, and everyone else who's sponsored my open source work! [You folks help make this possible.](https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fhmlongco)\n\n---\n\n## A Simple Factory\n \nMost 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.\n \n Factory is no exception. Here's a simple dependency registration that returns a service that conforms to `MyServiceType`.\n \n```swift\nextension Container {\n    var myService: Factory\u003CMyServiceType> { \n        Factory(self) { MyService() }\n    }\n}\n```\n\nUnlike 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. \n\nInjecting an instance of our service is equally straightforward. Here's just one of the many ways Factory can be used.\n\n```swift\nclass ContentViewModel: ObservableObject {\n    @Injected(\\.myService) private var myService\n    ...\n}\n```\nThis particular view model 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 `ContentViewModel` is created.\n\nAnd 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.\n\nBy 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.\n\nFor more examples of Factory definitions that define scopes, use constructor injection, and do parameter passing, see the [Registrations](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fregistrations) page.\n\n## Other Factory Resolution Methods\n\nEarlier we demonstrated how to use the ``Injected`` property wrapper. But it's also possible to bypass the property wrapper and talk to the factory yourself.\n\n```swift\nclass ContentViewModel: ObservableObject {\n    private let myService = Container.shared.myService()\n    private let eventLogger = Container.shared.eventLogger()\n    ...\n}\n```\nJust call the desired factory as a function and you'll get an instance of its managed dependency. It's that simple.\n\nIf you're into container-based dependency injection, note that you can also pass an instance of a container to a view model and obtain an instance of your service directly from that container.\n```swift\nclass ContentViewModel: ObservableObject {\n    let service: MyServiceType\n    init(container: Container) {\n        service = container.service()\n    }\n}\n```\nOr if you want to use a Composition Root structure, just use the container to provide the required dependencies to a constructor.\n\n```swift\nextension Container {\n    var myRepository: Factory\u003CMyRepositoryType> {\n        Factory(self) { MyRepository(service: self.networkService()) }\n    }\n    var networkService: Factory\u003CNetworking> {\n        Factory(self) { MyNetworkService() }\n    }\n}\n\n@main\nstruct FactoryDemoApp: App {\n    let viewModel = MyViewModel(repository: Container.shared.myRepository())\n    var body: some Scene {\n        WindowGroup {\n            NavigationView {\n                ContentView(viewModel: viewModel)\n            }\n        }\n    }\n}\n\n```\nFinally, Factory has a set of global dependency resolution functions.\n```swift\nfinal class NetworkService {\n    let preferences: Preferences = dependency(\\.preferences)\n    lazy var service: Service = dependency(\\.service, parameter: Mode.secret)\n    ...\n}\n```\nThese are discussed in detail below.\n\nFactory is flexible, and it doesn't tie you down to a specific dependency injection pattern or technique.\n\nSee [Resolutions](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fresolutions) for more examples.\n\n## Mocking\n\nIf we go back and look at our original view model code one might wonder why we've gone to all of this trouble? Why not simply say `let myService = MyService()` and be done with it? \n\nOr keep the container idea, but write something similar to this…\n\n```swift\nextension Container {\n    static var myService: MyServiceType { MyService() }\n}\n```\n\nWell, the primary benefit one gains from using a container-based dependency injection system is that we're able to change the behavior of the system as needed. Consider the following code:\n\n```swift\nstruct ContentView: View {\n    @StateObject var model = ContentViewModel()\n    var body: some View {\n        Text(model.text())\n            .padding()\n    }\n}\n```\n\nOur ContentView uses our view model, which is assigned to a StateObject. Great. But now we want to preview our code. How do we change the behavior of `ContentViewModel` so that its `MyService` dependency isn't making live API calls during development? \n\nIt's easy. Just replace `MyService` with a mock that also conforms to `MyServiceType`.\n\n```swift\n#Preview {\n    let _ = Container.shared.myService.register { MockService2() }\n    ContentView()\n}\n```\nNote the line in our preview code where we’re gone back to our container and registered a new closure on our factory. This function overrides the default factory closure.\n\nNow when our preview is displayed `ContentView` creates a `ContentViewModel` which in turn has a dependency on `myService` using the `Injected` property wrapper. And when the wrapper asks the factory for an instance of `MyServiceType` it now gets a `MockService2` instead of the `MyService` type originally defined.\n\nThis is a powerful concept that lets us reach deep into a chain of dependencies and alter the behavior of a system as needed.\n\nNote that Factory 2.5.1 made it even cleaner.\n```swift\n#Preview {\n    Container.shared.myService.preview { MockService2() }\n    ContentView()\n}\n```\nSee the [Previews](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fpreviews) documentation for more.\n\n## Testing\n\nThe mocking concept can also be used when writing unit tests. Consider the following...\n\n```swift\n@Suite(.container) \u002F\u002F note container trait\nstruct FactoryTests {\n\n    @Test func testLoaded() async {\n        Container.shared.accountProvider.register { MockProvider(accounts: .sampleAccounts) }\n        let model = Container.shared.someViewModel()\n        model.load()\n        #expect(model.isLoaded)\n    }\n\n    @Test func testEmpty() async {\n        Container.shared.accountProvider.register { MockProvider(accounts: []) }\n        let model = Container.shared.someViewModel()\n        model.load()\n        #expect(model.isEmpty)\n    }\n\n    @Test func testErrors() async {\n        Container.shared.accountProvider.register { MockProvider(error: .notFoundError) }\n        let model = Container.shared.someViewModel()\n        model.load()\n        #expect(model.errorMessage == \"Some Error\")\n    }\n    \n}\n```\n\nAgain, Factory makes it easy to reach into a chain of dependencies and make specific changes to the system as needed. This makes testing loading states, empty states, and error conditions simple.\n\n\nXcode 16.3's test trait support also makes it possible to run all of our tests in parallel! \n\nThe `.container` trait shown above provides a new, fresh instance of the main shared container to each one of the tests.\n\nSee the [Testing Documentation](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Ftesting) for more.\n\n## XCTest\n\nStill using XCTest? Don't worry. Factory works there too.\n\n```swift\nfinal class FactoryCoreTests: XCTestCase {\n\n    override func setUp() {\n        super.setUp()\n        Container.shared.reset()\n    }\n    \n    func testLoaded() throws {\n        Container.shared.accountProvider.register { MockProvider(accounts: .sampleAccounts) }\n        let model = Container.shared.someViewModel()\n        model.load()\n        XCTAssertTrue(model.isLoaded)\n    }\n    \n    \u002F\u002F other tests\n    \n}\n```\n\nBut we're not done yet. \n\nFactory has quite a few more tricks up its sleeve...\n\n## Scope\n\nIf you've used Resolver or some other dependency injection system before then you've probably experienced the benefits and power of scopes.\n\nAnd if not, the concept is easy to understand: Just how long should an instance of an object live?\n\nYou've no doubt stuffed an instance of a class into a variable and created a singleton at some point in your career. This is an example of a scope. A single instance is created and then used and shared by all of the methods and functions in the app.\n\nThis can be done in Factory just by adding a scope modifier.\n\n```swift\nextension Container {\n    var networkService: Factory\u003CNetworkProviding> { \n        self { NetworkProvider() }\n            .singleton\n    }\n    var myService: Factory\u003CMyServiceType> { \n        self { MyService() }\n            .scope(.session)\n    }\n}\n```\nNow whenever someone requests an instance of `networkService` they'll get the same instance of the object as everyone else.\n\nNote that the client neither knows nor cares about the scope. Nor should it. The client is simply given what it needs when it needs it. \n\nIf no scope is specified the default scope is unique. A new instance of the service will be instantiated and returned every time one is requested from the factory.\n\nOther common scopes are `cached` and `shared`. Cached items are persisted until the cache is reset, while shared items exist just as long as someone holds a strong reference to them. When the last reference goes away, the weakly held shared reference also goes away.\n\nFactory has other scope types, plus the ability to add more of your own. See [Scopes](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fscopes) for additional examples.\n\nScopes and scope management are powerful tools to have in your dependency injection arsenal.\n\n## Simplified Syntax\n\nYou may have noticed in the previous example that Factory also provides a bit of syntactical sugar that lets us make our definitions more concise. We simply ask the enclosing container to make a properly bound Factory for us using `self.callAsFunction { ... }`.\n\n```swift\nextension Container {\n    var sugared: Factory\u003CMyServiceType> { \n        self { MyService() }\n    }\n    var formal: Factory\u003CMyServiceType> { \n        Factory(self) { MyService() }\n    }\n}\n```\nBoth definitions provide the same exact result. The sugared function is even inlined, so there's not even a performance difference between the two versions.\n\n## Contexts\n\nOne powerful feature in Factory is contexts. Let's say that for logistical reasons whenever your application runs in debug mode you *never* want it to make calls to your application's analytics engine.\n\nEasy. Just register an override for that particular context.\n\n```swift\ncontainer.analytics.onDebug { \n    StubAnalyticsEngine()\n}\n```\nThere are other contexts for unit testing, for SwiftUI previews, and even when running **UITests** both in the simulator or when running an app on services like BrowserStack.\n\nFor a complete list, go to [Contexts](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fcontexts).\n\n## Debugging\n\nFactory can also help you debug your code. When running in DEBUG mode Factory allows you to trace the injection process and see every object instantiated or returned from a cache during a given resolution cycle.\n```\n0: Factory.Container.cycleDemo\u003CCycleDemo> = F:105553131389696\n1:     Factory.Container.aService\u003CAServiceType> = F:105553119821680\n2:         Factory.Container.implementsAB\u003CAServiceType & BServiceType> = F:105553119821680\n3:             Factory.Container.networkService\u003CNetworkService> = F:105553119770688\n1:     Factory.Container.bService\u003CBServiceType> = F:105553119821680\n2:         Factory.Container.implementsAB\u003CAServiceType & BServiceType> = C:105553119821680\n```\nThis can make it a lot easier to see the entire dependency tree for a given object or service.\n\nSee [Debugging](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fdebugging) for more on this and other features.\n\n## Observation \u002F Actor Isolation\n\nFactory also works with Observation, `@MainActor` and actor isolation in Swift concurrency. Just annotate the Factory as needed.\n\n```swift\n\u002F\u002F Observable view model isolated to @MainActor\n@MainActor\n@Observable\nclass ContentViewModel {\n    @ObservationIgnored @Injected(\\.myService) private var service\n    ...\n}\n\n\u002F\u002F Factory isolated to @MainActor\nextension Container {\n    @MainActor\n    var contentViewModel: Factory\u003CContentViewModel> {\n        self { ContentViewModel() }\n    }\n}\n\n\u002F\u002F View with injected view model\nstruct ContentView: View {\n    @InjectedObservable(\\.contentViewModel) var viewModel\n    var body: some View {\n        ...\n    }\n}\n```\n`InjectedObservable` was added to Factory 2.4.\n\nSee [SwiftUI](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit\u002Fswiftui) for more discussion.\n\n## Nonisolated Classes\n\nIf you're using global MainActors but have nonisolated service classes that need dependencies of their own then you may not be able use the \nvarious \"Injected\" property wrappers due to an issue with Swift 6.2.\n\nFactory has a global dependency resolution function that can be used in their place.\n\n```swift\nnonisolated final class NetworkService {\n    let preferences: Preferences = dependency(\\.preferences)\n    lazy var service: Service = dependency(\\.service, parameter: Mode.secret)\n    ...\n}\n```\nThese functions can also be useful when you want to hide Factory and Factory Shared Containers from the rest of your code base. Should you\never want to switch away from Factory, just expose your own `dependency` function with the same keyPaths.\n\nOne can also use them to pass parameters to Factory's, something the property wrappers don't allow.\n\n## Documentation\n\nA single README file barely scratches the surface. Fortunately, Factory is thoroughly documented. \n\nCurrent DocC documentation can be found in the project as well as online on [GitHub Pages](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit).\n\n## Demo Applications\n\nFactory includes a test bed application, `FactoryDemo`, that's used to test basic functionality and ensure various features are working properly.\n\nFactory 3.0 also has `MovieDemo`, a new TMDB movie browsing application that's been built to showcase how to use [Factory](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FFactory) and [Navigator](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FNavigator) in a modern, modular iOS application.\n\nIt can be obtained here: [MovieDemo](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FMovieDemo).\n\n## Installation\n\nWith the subsetting of CocoaPods, Factory 3.0 supports the Swift Package Manager. Period.\n\nFactory's primary import library is named `FactoryKit`. This is done in order to avoid SPM import conflicts between the library itself and the `Factory` object defined within the library.\n\nJust add the Factory package to your project target, select the `FactoryKit` library when asked, and then import `FactoryKit` in your Swift files where needed.\n\n```swift\nimport FactoryKit\n```\n\nIf you're using Swift Testing you'll probably also want to also import the `FactoryTesting` library and add it to your test target. \n\n**Do not, however, import `FactoryKit` into the Test target. That can lead to duplicate factories and indeterminate behavior.**\n\n> Note: If you still require CocoaPods support, drop down to Factory 2.5.3, or simply clone and embed Factory in your project directly.\n\n## Migration\n\nFactory 3.0.0 works with SPM, Xcode 26 under Strict Concurrency guidelines, and with Swift Testing.\n\nIf you're a current Factory user you'll need to update your code and switch from importing `Factory` to importing `FactoryKit`. This avoids SPM naming conflicts between the import library name and the primary `Factory` object.\n\nTo do so, open your project in Xcode and...\n\n1. Select `File > Packages > Update to Latest Package Versions`\n2. Select `File > Packages > Reset Package Caches`\n3. Go to your application target, remove the `Factory` library, and add the `FactoryKit` library\n4. Go a global search and replace, renaming `import Factory` to `import FactoryKit`\n5. Clean and build your project.\n\nYou may need to do the same for any other targets or modules that imported Factory.\n\nOne other significant change lies in MainActor Factory definitions. Factory 2.x required a definition that needed an additional `@MainActor` embedded in the Factory closure.\n\n```swift\n@MainActor\nvar contentViewModel: Factory\u003CContentViewModel> {\n    self { @MainActor in ContentViewModel() }\n}\n```\nSomething that wasn't the most intuitive thing in the world. Factory 3.0 simplifies that.\n\n```swift\n@MainActor\nvar contentViewModel: Factory\u003CContentViewModel> {\n    self { ContentViewModel() }\n}\n```\n\n## Discussion Forum\n\nDiscussion and comments on Factory can be found in [Discussions](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FFactory\u002Fdiscussions). Go there if you have something to say or if you want to stay up to date.\n\n## License\n\nFactory is available under the MIT license. See the LICENSE file for more info.\n\n## Sponsor Factory!\n\nMany thanks to Mercedes-Benz, Süddeutsche Zeitung, and everyone else who's sponsored my open source work!\n\nIf you want to support my work on Factory, Navigator, and my other projects and articles, please consider a [GitHub Sponsorship](https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fhmlongco)! \n\nMany levels exist for increased support and even for mentorship and company training. \n\nOr you can just buy me a cup of coffee!\n\n## Author\n\nFactory is designed, implemented, documented, and maintained by [Michael Long](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fhmlong\u002F), a Lead iOS Software Engineer and a Top 1,000 Technology Writer on Medium.\n\n* LinkedIn: [@hmlong](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fhmlong\u002F)\n* Medium: [@michaellong](https:\u002F\u002Fmedium.com\u002F@michaellong)\n* BlueSky: [@hmlongco](https:\u002F\u002Fbsky.app\u002Fprofile\u002Fhmlongco.bsky.social)\n\nMichael was also one of Google's [Open Source Peer Reward](https:\u002F\u002Fopensource.googleblog.com\u002F2021\u002F09\u002Fannouncing-latest-open-source-peer-bonus-winners.html) winners in 2021 for his work on Resolver.\n\n## Contributors\n\nSpecial thanks to Ákos Grabecz (agrabz) and Mahmood Tahir (tahirmt) for their recent contributions that ensure Factory works hand-in-hand with Swift Testing. \n\n## Additional Resources\n\n* [Factory Documentation](https:\u002F\u002Fhmlongco.github.io\u002FFactory\u002Fdocumentation\u002Ffactorykit)\n* [MovieDemo: A modern, modular iOS application that uses Factory and Navigator](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FMovieDemo)\n* [Factory 1.0 and Functional Dependency Injection](https:\u002F\u002Fbetterprogramming.pub\u002Ffactory-and-functional-dependency-injection-2d0a38042d05)\n* [Factory 1.0: Multiple Module Registration](https:\u002F\u002Fbetterprogramming.pub\u002Ffactory-multiple-module-registration-f9d19721a31d?sk=a03d78484d8c351762306ff00a8be67c)\n* [Resolver: A Swift Dependency Injection System](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FResolver)\n* [Inversion of Control Design Pattern ~ Wikipedia](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInversion_of_control)\n* [Inversion of Control Containers and the Dependency Injection pattern ~ Martin Fowler](https:\u002F\u002Fmartinfowler.com\u002Farticles\u002Finjection.html)\n* [Nuts and Bolts of Dependency Injection in Swift](https:\u002F\u002Fcocoacasts.com\u002Fnuts-and-bolts-of-dependency-injection-in-swift\u002F)\n* [Dependency Injection in Swift](https:\u002F\u002Fcocoacasts.com\u002Fdependency-injection-in-swift)\n* [Swift 5.1 Takes Dependency Injection to the Next Level](https:\u002F\u002Fmedium.com\u002Fbetter-programming\u002Ftaking-swift-dependency-injection-to-the-next-level-b71114c6a9c6)\n* [Builder: A Declarative UIKit Library (Uses Factory in Demo)](https:\u002F\u002Fgithub.com\u002Fhmlongco\u002FBuilder)\n","Factory 是一个为 Swift 和 SwiftUI 设计的现代容器依赖注入框架。它支持多种依赖注入策略和技术，包括容器、作用域、参数传递、上下文、装饰器等，并且与 SwiftUI 高度兼容。Factory 具备高性能、编译时安全、简洁定义和灵活性等特点，适用于 iOS 和 macOS 平台上的各种架构模式（如 MVVM、MVP、Clean 和 VIPER）。此外，它还提供了详尽的文档和示例代码，确保了开发者的易用性和项目的可测试性。对于需要在 Swift 项目中实现依赖注入，特别是使用 SwiftUI 构建用户界面的开发者来说，Factory 是一个轻量级且功能强大的选择。",2,"2026-06-11 03:10:21","top_language"]