{"id":28388517,"url":"https://github.com/swinject/swinjectautoregistration","last_synced_at":"2025-10-27T09:36:02.975Z","repository":{"id":46618964,"uuid":"67207074","full_name":"Swinject/SwinjectAutoregistration","owner":"Swinject","description":"Swinject extension to automatically register your services","archived":false,"fork":false,"pushed_at":"2024-06-28T22:00:07.000Z","size":1750,"stargazers_count":257,"open_issues_count":1,"forks_count":45,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-31T06:03:02.726Z","etag":null,"topics":["auto-registration","dependency-injection","swift","swinject"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Swinject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-02T08:52:26.000Z","updated_at":"2025-05-22T20:57:34.000Z","dependencies_parsed_at":"2024-03-28T16:38:56.902Z","dependency_job_id":"3d4d4e96-c9f6-4bb5-a4a6-c787778e3485","html_url":"https://github.com/Swinject/SwinjectAutoregistration","commit_stats":{"total_commits":164,"total_committers":23,"mean_commits":7.130434782608695,"dds":0.4695121951219512,"last_synced_commit":"89f9357680ed65dbc95b66732fe3338aca79064a"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/Swinject/SwinjectAutoregistration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swinject%2FSwinjectAutoregistration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swinject%2FSwinjectAutoregistration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swinject%2FSwinjectAutoregistration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swinject%2FSwinjectAutoregistration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Swinject","download_url":"https://codeload.github.com/Swinject/SwinjectAutoregistration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swinject%2FSwinjectAutoregistration/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262212626,"owners_count":23275965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-registration","dependency-injection","swift","swinject"],"created_at":"2025-05-30T21:39:32.809Z","updated_at":"2025-10-27T09:36:02.912Z","avatar_url":"https://github.com/Swinject.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"SwinjectAutoregistration\n========\n\n[![Build Status](https://travis-ci.org/Swinject/SwinjectAutoregistration.svg?branch=master)](https://travis-ci.org/Swinject/SwinjectAutoregistration)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![CocoaPods Version](https://img.shields.io/cocoapods/v/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration)\n[![License](https://img.shields.io/cocoapods/l/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration)\n[![Platform](https://img.shields.io/cocoapods/p/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration)\n[![Swift Version](https://img.shields.io/badge/Swift-5-F16D39.svg?style=flat)](https://developer.apple.com/swift)\n\nSwinjectAutoregistration is an extension of Swinject that allows to automatically register your services and greatly reduce the amount of boilerplate code.\n\n## Requirements\n\n- iOS 11.0+ / Mac OS X 10.13+ / tvOS 11.0+\n- Xcode 14.3+\n\n## Installation\n\nSwinject is available through [Carthage](https://github.com/Carthage/Carthage), [CocoaPods](https://cocoapods.org) or [Swift Package Manager](https://swift.org/package-manager/).\n\n### Carthage\n\nTo install Swinject with Carthage, add the following line to your `Cartfile`.\n\n```\ngithub \"Swinject/Swinject\" \"2.9.1\"\ngithub \"Swinject/SwinjectAutoregistration\" \"2.9.1\"\n```\n\nThen run `carthage update --use-xcframeworks --no-use-binaries` command or just `carthage update --use-xcframeworks`. For details of the installation and usage of Carthage, visit [its project page](https://github.com/Carthage/Carthage).\n\n### CocoaPods\n\nTo install Swinject with CocoaPods, add the following lines to your `Podfile`.\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '11.0' # or platform :osx, '10.13' if your target is OS X.\nuse_frameworks!\n\npod 'Swinject', '2.9.1'\npod 'SwinjectAutoregistration', '2.9.1'\n```\n\nThen run `pod install` command. For details of the installation and usage of CocoaPods, visit [its official website](https://cocoapods.org).\n\n### Swift Package Manager\n\nin `Package.swift` add the following:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Swinject/SwinjectAutoregistration.git\", from: \"2.9.1\")\n],\ntargets: [\n    .target(\n        name: \"MyProject\",\n        dependencies: [..., \"SwinjectAutoregistration\"]\n    )\n    ...\n]\n```\n\n### Registration\n\nHere is a simple example to auto-register a pet owner\n\n```swift\nlet container = Container()\ncontainer.register(Animal.self) { _ in Cat(name: \"Mimi\") } // Regular register method\ncontainer.autoregister(Person.self, initializer: PetOwner.init) // Autoregistration\n```\n\nwhere PetOwner looks like this:\n\n```swift\nclass PetOwner: Person {\n    let pet: Animal\n\n    init(pet: Animal) {\n        self.pet = pet\n    }\n}\n```\n\nThe `autoregister` function is given the `PetOwner` initializer `init(pet:Animal)`. From its signature Swinject knows that it needs a dependency `Animal` and resolves it from the container. Nothing else is needed.\n\nAutoregistration becomes especially useful when used to register services with many dependencies. Compare autoregistration code:\n\n```swift\ncontainer.autoregister(MyService.self, initializer: MyService.init)\n```\n\nwith equivalent code in pure Swinject:\n\n```swift\ncontainer.register(MyService.self) { r in\n    MyService(dependencyA: r.resolve(DependencyA.self)!, dependencyB: r.resolve(DependencyB.self)!, dependencyC: r.resolve(DependencyC.self)!, dependencyD: r.resolve(DependencyD.self)!)\n}\n```\n\nAnother advantage is that if you add more dependencies during the development the registration code doesn't have to be rewritten.\n\n\n#### Registration with name\nService can be also given name - same as with the regular register method.\n\n```swift\ncontainer.autoregister(Person.self, name: \"johnny\", initializer: PetOwner.init)\n\n```\n\n#### Arguments\nYou can also use auto-registration for services with dynamic arguments. Pet owner whose name needs to be passed as argument is defined like this:\n\n```swift\nclass PetOwner: Person {\n    let name: String\n    let pet: Animal\n\n    init(name: String, pet: Animal) {\n        self.name = name\n        self.pet = pet\n    }\n}\n```\n\nAnd registered like this\n\n```swift\ncontainer.autoregister(Person.self, argument: String.self, initializer: PetOwner.init)\n```\n\nSwinject will register `Person` with the argument of type `String`. When `container.resolve(Person.self, argument: \"Michael\")` is called Swinject won't try to resolve `String` as dependency but instead pass \"Michael\" as the name.\n\nTo also pass pet as argument you can call\n\n```swift\ncontainer.autoregister(Person.self, arguments: String.self, Animal.self, initializer: PetOwner.init)\n//or\ncontainer.autoregister(Person.self, arguments: Animal.self, String.self, initializer: PetOwner.init)\n```\n\n\u003e The order of the arguments listed is interchangeable. The auto-registration can't be used with more arguments and/or dependencies of the same type.\n\n\n### What kind of sorcery is this?\n\nWondering how does that work? Generics are heavily leveraged for the auto-registration. For registering service with two dependencies something similar to a following function is used:\n\n```swift\npublic func autoregister\u003cService, A, B\u003e(_ service: Service.Type, initializer: (A, B) -\u003e Service) -\u003e ServiceEntry\u003cService\u003e {\n   return self.register(service.self, factory: { r in\n       return initializer(r.resolve(A.self)!, r.resolve(B.self)!)\n   } as (ResolverType) -\u003e Service)\n}\n```\n\nThe initializer is a function like any other. By passing it as a parameter its dependencies can be inferred as `(A, B)` and automatically resolved. These functions are generated for up to 20 dependencies. Checkout the [code](https://github.com/Swinject/SwinjectAutoregistration/blob/master/Sources/AutoRegistration.swift) for more info.\n\n### Operators ###\nThis extension also aims to reduce the amount of boilerplate while improving readability of the registration code. For that reason the operator `~\u003e` is introduced.\n\n```swift\nPetowner(pet: r~\u003e)\n\n// equivalent to\n\nPetowner(pet: r.resolve(Animal.self)!)\n```\n\nThe dependency is again inferred from the type in the initializer. To specify a concrete class you can use:\n\n```swift\nPetowner(pet: r ~\u003e Cat.self)\n```\n\nTo use a named service:\n\n```swift\nPetowner(pet: r ~\u003e (Cat.self, name: \"mimi\"))\n```\n\nor to pass argument/s:\n\n```swift\nPetowner(pet: r ~\u003e (Cat.self, argument: \"Mimi\"))\nPetowner(pet: r ~\u003e (Cat.self, arguments: (\"Mimi\", UIColor.black)))\n\n```\n\n### Limitations ###\nWhen a service has multiple initializers, swift compiler can't be sure which should be used and you will get a `ambigious use of init(x: y: z:)`. This can also happen if the service is extending another class that have initializer with the same number of arguments.\n\nThe solution is to specify the initializer like this:\n\n```\ncontainer.autoregister(Person.self, initializer: PetOwner.init(name:pet:))\n```\n\nAuto-registration **can't** be used with **named dependencies** in their initializers. There is no way to get a name of dependency from the initializer. For example, following code can't be auto-registered:\n\n```swift\ncontainer.register(Animal.self, name: \"mimi\") { _ in Cat(name: \"Mimi\") }\ncontainer.register(Animal.self, name: \"charles\") { _ in Cat(name: \"Charles\") }\ncontainer.register(Person.self) {\n    PetOwner(pet: r.resolve(Animal.self, name: \"mimi\")\n}\n```\n\n### Swift 5.3\nSince Swift 5.3 the compiler behaves differently when infering initializers in structs that have variables with a default value:\n\n```swift\nstruct Cat {\n    let height: Int = 50\n}\n```\n\nCompiler will generate two init functions:\n\n`Cat.init` and `Cat.init(height:)`\n\nSince the Swift 5.3 the following registration\n\n```swift\ncontainer.autoregister(Animal.self, initializer: Cat.init)\n```\n\nwill try to use the `Cat.init(height:)` which will then fail with `Unresolved service: Int Initializer: (Int) -\u003e Animal`\n\nSolution is to make the compiler use the init without a parameter\n\n```swift\ncontainer.autoregister(Animal.self, initializer: Cat.init as () -\u003e Cat)\n```\n\n## For Maintainers\n\n  ### Making a new release version\n\n  Our release procedure is described as [Makefile](https://github.com/Swinject/SwinjectAutoregistration/blob/master/Makefile). Run `make help` coomand for more info.\n\n## Credits\n\nSwinjectAutoregistration generics is inspired by:\n- [Curry](https://github.com/thoughtbot/Curry) - [Thoughtbot](https://thoughtbot.com/)\n\n## License\n\nMIT license. See the [LICENSE file](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswinject%2Fswinjectautoregistration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswinject%2Fswinjectautoregistration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswinject%2Fswinjectautoregistration/lists"}