Skip to content

broken-bytes/Syringe

Repository files navigation

Syringe

Build GitHub tag (latest by date) Swift Discord Reliability Rating

Syringe is a lightweight dependency(DI) framework written in Swift. It aims to provide an intuitive and non-invasive way to realise Inversion of Control(IoC) in applications written in Swift.

Unlike other dependency frameworks, Syringe aims for simplicity and ease-of-use via an extensive custom DSL.

The core features of Syringe:

  • Full-features dependency injection
  • Intuitive and clever custom DSL
  • Non-invasive:
    • No property wrappers
    • No code-generation
    • Only use Syringe where you need to
  • Tested on macOS, Windows and Linux.

Getting Started

Setup

Syringe is available via the Swift Package Manager.

Just add it as a dependency:

dependencies: [
  ...
  .package(url: "https://github.com/broken-bytes/Syringe", from: "v0.2.1-a"),
]

Now Syringe is ready for import:

import Syringe

You can now use Syringe from your code.

Initialising Syringe

Syringe's core is the Container. It is the central touchpoint for all interactions with Syringe.

There are two types of Container:

  • An ordinary Container
  • A global scope Container

Creating a global scope Container is the preferred way as it enables the use of the free DSL functions Syringe provides.

Creating a global scope Container:

import Syringe

class DependencyHandler {
    init() {
        injectSyringe {
            modules {
                // Modules go here
            }
        }
    }
}

Creating Modules

Modules are dependency lists in Syringe. Defining a module is simple:

let appModule = module {
    // Dependencies go here
}

Adding Dependencies

Adding dependencies to modules is done via the module DSL:

let appModule = module {
    singleton { _ in YourType() }
    factory { _ in Int.random(0..<5) }
}

Resolving Dependencies

Resolving dependencies is done via either the module or application DSL:

class Service {
    let value: Int

    init(value: Int) { 
        self.value = value
    }
}

let appModule = module {
    // Resolving at module level
    singleton { module in YourType(value: module.get()) }
    factory { _ in Int.random(0..<5) }
}

class View {
    // Resolving at global level
    let service: Service = get()!

    init() {

    }
}

Documentation

The full documentation can be found under Documentation