Skip to content

A lightweight dependency injection library for Swift and SwiftUI projects.

License

Notifications You must be signed in to change notification settings

rmichelberger/Inject

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inject

SwiftPM License: MIT

A leightweigth dependency injection library for Swift and SwiftUI projects.

Installing Inject

Inject supports Swift Package Manager.

Swift Package Manager

To install Inject using Swift Package Manager you can follow the tutorial published by Apple using the URL for the Inject repo with the current version:

  1. In Xcode, select “File” → “Add Packages...”
  2. Enter https://github.com/rmichelberger/Inject

or you can add the following dependency to your Package.swift:

.package(url: "https://github.com/rmichelberger/Inject/", from: "1.0.0")

Usage

1. Dependencies

You need to define the providers for each dependency in the project.

Signature of @Provides:

@Provides var dependency: () -> Dependency = { Dependency() }

The provider function will be called, each time the dependency is injected.

Singleton

Signature of @Singleton:

@Singleton var signleton: Singleton = Singleton()

An instance of the singleton is stored, and this instance is provided each time it is injected.

Example:

@Singleton var repository: Repository = RepositoryImpl()

Example for defining the project dependencies:

func Dependencies() {

    @Provides var apiService = { ApiService() }
    @Provides var retroSwift = {
        let logger = SimpleLogger()
        let client = OkHttpClient(logger: logger)
        return RetroSwift(client: client)
    }
    @Provides var useCase = { UseCase() }
        

    // ViewModels
    @Provides var artListViewModel = { ArtListViewModel() }
    @Provides var artDetailViewModel = { ArtDetailViewModel() }
    
    // Singletons
    @Singleton var repository: Repository = RepositoryImpl()
}

Don't forget to initialize the dependencies on app start:

@main
struct MyApp: App {
    
    init() {
        Dependencies()
    }

2. Inject

To inject dependencies, use @Inject:

@Inject private var dependency: Dependency

Example:

final class RepositoryImpl: Repository {

    @Inject private var apiService: ApiService

    func getArtList() async throws -> [ArtData] {
        try await apiService.getArtList().data
    }
    
    func getArtDetail(id: Int) async throws -> ArtDetailData {
        try await apiService.getArtDetail(id: id).data
    }
}

Singleton

For singelton dependency use @Singleton:

@Singleton private var repository: Repository

View models

View models can be injected by ViewModel():

@StateObject private var viewModel: ArtListViewModel = ViewModel()

Overview

Define Inject Scope
@Provide @Inject Lifecycle is defined in the provider function
@Singleton @Singleton App lifecycle

TODO

  • Improve unit test coverage.

Contributing

We always appreciate contributions from the community. Please make sure to cover your changes with unit tests.

Inspired by hilt.