Swiftpack.co -  lloydkeijzer/SwimpleInjection as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
lloydkeijzer/SwimpleInjection
Simple dependency injection in Swift
.package(url: "https://github.com/lloydkeijzer/SwimpleInjection.git", from: "1.1.4")

SwimpleInjection

version issues license size

Simple dependency injection with Swift.

SwimpleInjection is part of the Swimple packages series. Swimple stands for Simple Swift. These packages make coding with Swift simpler and more convenient.

Swift Package Manager 📦

From within Xcode 11 or up you can add SwimpleInjection as a Swift Package:

  1. Select your project
  2. Go to Swift packages
  3. Add a package (+)
  4. Enter https://github.com/lloydkeijzer/SwimpleInjection.git as the package repository url
  5. Select the version you want to use and click next

You're now able to import SwimpleInjection in your source code 🎉

Basics 🎓

Dependency Injection with SwimpleInjection starts with registering the services(concrete class types) or workers(protocol types) you want to resolve later on. You’ve three options for registering a service:

Automatic example 🤖

Since version 1.1.0 it's possible to automatically register your services instead of resolving them with a Handler or Assembler. Just provide the type of Service/Worker and its initialize method. There are a few constraints though:

  • 9 arguments can currently be automatically resolved per initializer method
  • All the initializer method its arguments have to be registered in the same container as the one resolving the Service
Container.main.autoRegister(Worker.self, initializer: Service.init)

Handler example

Using a handler for less complex services.

Container.main.register(Worker.self) { (container) -> Service in
  return Service(
    a: container.resolve(WorkerA.self),
    b: container.resolve(WorkerB.self)
  )
}

Assembler example

Using a dedicated Assembler for more complex services.

final class ServiceAssembler: Assembler {
  func resolve(using container: Resolver) -> AnyObject {
    return Service(
        a: container.resolve(WorkerA.self),
        b: container.resolve(WorkerB.self)
     )
  }
}
Container.main.register(assembler: ServiceAssembler(), for: Worker.self)

Resolve example

We can resolve our registered services by calling the resolve method on the Container.

let service = Container.main.resolve(Worker.self)

Containers

A Container object is able to register services and resolve them later on. Most of the time you’ll use the default Container.main instance. But if your use case requires to have multiple containers you can create them by calling let myCustomContainer = Container().

Merging Containers Example

When working in multiple frameworks or targets you could end up having multiple containers, that need to be merged in your main target.

let containerA = Container()
containerA.autoRegister(ClassA.self, initializer: ClassA.init)

let containerB = Container()
containerB.autoRegister(ClassB.self, initializer: ClassB.init)

let containerC = Container()
containerC.register(ClassC.self) { (container) -> ClassC in
  return ClassC(
    a: container.resolve(ClassA.self),
    b: container.resolve(ClassB.self)
  )
}

// Merging containers a, b and c into the main container
Container.main.merge(with: containerA)
Container.main.merge(with: containerB)
Container.main.merge(with: containerC)

let c = Container.main.resolve(ClassC.self)
c.hello() // 👋🏻 Hello from Class C      

Shared Services

With SwimpleInjection you can get rid of the shared singleton boilerplate by declaring your Service to be resolved as a .singleObject. This makes sure the service will only be resolved once and the Container saves a reference to the object. The next time the same service asks to be resolved, it will serve the reference to the saved object.

Single Object Example

Container.main.autoRegister(
  SharedWorker.self, 
  as: .singleObject, // default is .uniqueObject
  initializer: SharedWorker.init
)

let shared1 = Container.main.resolve(SharedWorker.self)
shared1.count += 1

let shared2 = Container.main.resolve(SharedWorker.self)
shared2.count += 1

print(shared1.count) // 2
print(shared2.count) // 2

GitHub

link
Stars: 1
Last commit: 1 year ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

Bug fix 🐛
1 year ago

Corrected a typo.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API