Skip to content

antoniopantaleo/didi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Didi

image-no-bg

Swift 6.2 SwiftPM

Platform macOS Platform iOS Platform tvOS Platform watchOS Platform visionOS

didi (pronounced /diː diː/ or dee dee) is a dependency injection abstracion layer, written with dependency inversion in mind.

It leverages powerful Swift features like result builders, property wrappers, operators and parameter packs to offer a robust, friendly and compile-time safe API.

Important

didi is NOT a dependency injection framework

Architecture

sequenceDiagram
    actor Client as Your App
    participant Container as Container
    box Gray Adapters
      participant DI as DI Framework
    end

    note over Container,DI: boundary
    Client ->> Container: register(type, factory)
    Container -->> DI: register()

    Client ->>+ Container: resolve(type)
    Container -->> DI: resolve()
    DI -->> Container: service
    Container ->- Client: service
Loading

Installation

Swift Package Manager

Add didi to your dependencies:

dependencies: [
    .package(url: "https://github.com/antoniopantaleo/didi.git", from: "3.0.0")
]

Then depend on the products you need:

.target(
    name: "YourApp",
    dependencies: [
        .product(name: "Didi", package: "didi")
    ]
)

Quick start

Here's a brief look on how didi API looks like:

Registration

You can register a service to a type using the special ~> syntax, listing all of your injections like this:

import Didi

let container: any Container = MyContainer()

container.register {
    Int.self ~> 2
    HTTPClient.self ~> URLSessionHTTPClient(session: .shared)
    String.self ~> {
        var result = "Hello"
        result += ", Didi"
        return result
    }
    // ...
}

Note

You do not need to write commas within the registration closure

Registration offers compile-time safety thanks to Swift's powerful generics system. Wrong registration like the following will be clearly reported by the compiler:

  container.register {
    Int.self ~> "hello didi" // ⛔️ Binary operator '~>' cannot be applied to operands of type 'Int.Type' and 'String'
  }

Resolution

Once registered, a service can be safely resolved using the @Injected property wrapper:

@Injected(in: container) var greeting: String? // Or simply '@Injected' if you provide a default container
print(greeting ?? "Missing")

Backends

didi comes with a set of pre-implemented adapters (or backends) based on popular existing frameworks like:

Contributing

Issues and pull requests are welcome. Feel free to contribute!

About

A Dependency Inversion-first Dependency Injection abstraction layer

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages