Simple dependency injection in Swift

What's New

Bug fix 🐛


Corrected a typo.


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. Selecting 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)


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

  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


  • Swift Tools 5.1.0
View More Packages from this Author


  • None
Last updated: Wed Jan 04 2023 00:32:34 GMT-0500 (GMT-05:00)