{"id":21801972,"url":"https://github.com/illescasdaniel/inject-swift","last_synced_at":"2025-07-01T04:08:11.918Z","repository":{"id":119505595,"uuid":"265335433","full_name":"illescasDaniel/Inject-Swift","owner":"illescasDaniel","description":"Easy dependency injection for swift with nice scalability","archived":false,"fork":false,"pushed_at":"2023-02-02T20:58:51.000Z","size":37,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T18:51:38.898Z","etag":null,"topics":["autowired","dependency-injection","di","inject","injection","singleton","swift"],"latest_commit_sha":null,"homepage":"https://itnext.io/9aa1015d8342","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/illescasDaniel.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,"zenodo":null}},"created_at":"2020-05-19T18:50:49.000Z","updated_at":"2025-03-24T17:00:16.000Z","dependencies_parsed_at":"2023-03-13T12:40:04.421Z","dependency_job_id":null,"html_url":"https://github.com/illescasDaniel/Inject-Swift","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/illescasDaniel/Inject-Swift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FInject-Swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FInject-Swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FInject-Swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FInject-Swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/illescasDaniel","download_url":"https://codeload.github.com/illescasDaniel/Inject-Swift/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FInject-Swift/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262893664,"owners_count":23380712,"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":["autowired","dependency-injection","di","inject","injection","singleton","swift"],"created_at":"2024-11-27T11:21:54.782Z","updated_at":"2025-07-01T04:08:11.910Z","avatar_url":"https://github.com/illescasDaniel.png","language":"Swift","readme":"# Inject\n[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/illescasDaniel/Inject-swift/blob/master/LICENSE)\n\nEasy dependency injection for swift, compatible with structs and classes.\n\n## Basic example\n\n1. Define your **protocol**\n2. Define a **class** (or struct) implementing it\n3. Create a **static variable of the dependency resolver**\n4. **Add the dependency** using the dependency resolver\n5. **Inject it** using `@Inject`\n\n```swift\n// 1\nprotocol UserRepository {\n    func add(user: String) -\u003e Int\n}\n\n// 2\nclass DefaultUserRepository: UserRepository {\n    func add(user: String) -\u003e Int {\n        return 1\n    }\n}\n\n// \"3\"\nclass DependencyInjection {\n    static let dependencies: DependencyResolver = DefaultDependencyResolver()\n}\n\n// 4. somewhere (like in your main / AppDelegate)\nDependencyInjection.dependencies.add(\n    UserRepository.self,\n    using: DefaultUserRepository() // autoclosure\n)\n\n// 5\nstruct InjectedDependenciesExample {\n\n    @Inject(resolver: DependencyInjection.dependencies)\n    private var userRepository: UserRepository\n\n    init() {}\n\n    init(\n        userRepository: UserRepository?\n    ) {\n        // if you pass a non-nil `userRepository`, it will asign it to your local `self.userRepository`; else, it will use the injected dependency (don't forget the \"$\")\n        self.$userRepository = userRepository\n    }\n}\n\n/* OK examples: */\n\nlet example1 = InjectedDependenciesExample()\n\n// explicitly acknowledge that it will use the injected value\nlet example2 = InjectedDependenciesExample(userRepository: nil)\n\n// explicitly use another value instead of the default/injected one\nlet example3 = InjectedDependenciesExample(userRepository: OtherUserRepository())\n```\n\n### **TIP**: declare a default constructor extension for `@Inject` that uses your dependency injection\n```swift\nextension Inject {\n    init() {\n        self.init(resolver: DependencyInjection.dependencies)\n    }\n}\n\n// Result :) niiice\n\nstruct InjectedDependenciesExample {\n\n    @Inject()\n    private var userRepository: UserRepository\n\n    init() {}\n\n    init(\n        userRepository: UserRepository?\n    ) {\n        self.$userRepository = userRepository\n    }\n}\n```\n\n## Singleton example\n\n```swift\n// 1\nclass FakeUserDefaultsManager {\n\n    init() {}\n\n    var username: String {\n        get { \"Daniel\" }\n        set { /*...*/ }\n    }\n    // ...\n    \n    // no need for a static variable here, since we'll use the resolver\n}\n\n// \"2\"\nclass DependencyInjection {\n    static let singletons: SingletonResolver = DefaultSingletonResolver()\n}\n\n// 3. somewhere (like in your main / UIApplicationMain)\n// you can also use a protocol and a value as with the previous example\nDependencyInjection.singletons.add(\n    FakeUserDefaultsManager() /* autoclosure */\n)\n\nextension InjectSingleton {\n    init() {\n        self.init(resolver: DependencyInjection.singletons)\n    }\n}\n\nstruct InjectedDependenciesExample2 {\n\n    @InjectSingleton()\n    private var userDefaults: FakeUserDefaultsManager\n\n    // If you don't want to use `init` you can just use\n    @AutoWiredSingleton()\n    private var userDefaults: FakeUserDefaultsManager\n\n    init() {}\n\n    init(\n        userDefaults: FakeUserDefaultsManager?\n    ) {\n        self.$userDefaults = userDefaults\n    }\n}\n```\n\n## FAQ\n\u003e 1 - Do I need to use `@Inject` or `@AutoWired`\n\nNo, you can just do `DependencyInjection.dependencies.resolve(YourTypeHere.self)` and it will give you the instance.\n\n\u003e 2 - How can I use it with structs? Should I?\n\nGood question, you can if you want.\n**Using structs in your normal dependencies should be OK** (unless you use some shared code in that struct or something), because the resolver will just store a function that returns a value.\n\nBut you should not use structs directly in your singleton dependencies (because you want to use the same values across your program) unless wrapped by a class (like the `Box\u003cT\u003e` class provided in this library) or if added like this:\n`DependencyInjection.singletons.addBox(...)` . When you later use `@InjectSingleton` you should declare a local variable like `Box\u003cMyStructSingleton\u003e`, this will behave as a class because of the `Box` type (which encloses a type inside a class).\n\nYou can also use `AutoWiredBoxSingleton` for these case:\n```swift\n@AutoWiredBoxSingleton()\nvar userDefaultsStruct: FakeUserDefaultsManagerStruct\n// FakeUserDefaultsManagerStruct is a struct, and `userDefaultsStruct` will return that value, but if you do any modification it behaves like a normal class...\n```\n\nAbout using it if is not a singleton I would say you shouln't have any problems if that struct doesn't mutate. If it does, consider wrapping the value inside the `Box` type.\n\n\u003e 3 - TL;DR too many steps...\n\nActually... you only need to create the dependency injection class and the Inject extensions once, so after that you just need to use `@Inject` and remember to add the dependencies before using it.\n\n\u003e 4 - If I don't use, for any reason, the injected value or a singleton, would that still create an instance?\n\nNo, until you use the value, it is not retrieved from the dependencies container.\n\nSame happends with singletons. The 'singleton resolver' stores the singleton **as a function** until is first called, then it stores its reference value.\n\n\u003e 4 - Do I need a library like this for simple dependencies on my small app?\n\nProbably not, but you might consider using it if your app grows or if you just like the way of handling dependencies.\n\n**I wrote about it in my article at medium**: https://itnext.io/9aa1015d8342\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fillescasdaniel%2Finject-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fillescasdaniel%2Finject-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fillescasdaniel%2Finject-swift/lists"}