Skip to content

Simple dependency injection library using Swift property wrappers.

License

Notifications You must be signed in to change notification settings

munirwanis/Vaccine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vaccine

Version Swift Package Manager Platforms Build License Tweet

Simple dependency injection library using Swift property wrappers

Tired of creating a lot of property on initializers of your classes so it's easier to test them? With Vaccine is possible to define properties in your classes using @propertyWrappers in a very simple way!

Installation

Swift Package Manager

In Xcode go to File->Swift Packages->Add Package Dependency... and paste the url:

https://github.com/munirwanis/Vaccine.git

If you are adding this package as a dependency to another package, paste this on your Package.swift file:

dependencies: [
    .package(url: "https://github.com/munirwanis/Vaccine.git", .upToNextMajor(from: "1.0.0" )),
]

Manual

Since this project has no dependencies, it's possible to drag the source files to your project.

Other package managers

If manual or SPM are not a option, pull requests will be very welcome to help support other platforms.

Compatibility

  • Swift 5.1+
  • Xcode 11+

Usage

Register dependencies

You can use the starting point of your application to register the dependencies that will be resolved later. Let's say we have a protocol for a service called SomeServiceProtol, and I want to resolve it with my class SomeService.

import Foundation
import Vaccine

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    
    func application(_ application: UIApplication,
                     configurationForConnecting connectingSceneSession: UISceneSession,
                     options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        
        // Registers the dependency for my service
        Vaccine.setCure(for: SomeServiceProtocol.self, with: SomeService())

        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
}

You can also set the property isUnique to true to ensure that the object injected is singleton.

Vaccine.setCure(for: SomeServiceProtocol.self, isUnique: true, with: SomeService())

If your object needs to do some complex things you can also pass the resolver as a closure, like this:

// Can also use `isUnique` property
Vaccine.setCure(for: SomeServiceProtocol.self) {
    let item = ["Hello", "World"].randomElement() ?? ""
    return SomeService(text: item)
}

Resolve dependencies

To resolve dependencies is pretty simple, simply use @Inject property wrapper inside your class:

class SomeViewModel {
    // Will instantiate or get an already instantiated (if singleton) version of  `SomeService`
    @Inject(SomeServiceProtocol.self) var service
    
    func getText() -> String {
        service.getText()
    }
}

Contributions

Found a bug or have a improvement suggestion? Open a issue or help by submitting a Pull Request! 😊