Giter Club home page Giter Club logo

dependencyinjectable's Introduction

Dependency Injectable

This library offers a lightweight and powerful solution for integrating dependency injection into SwiftUI applications. Leveraging the latest native APIs, it facilitates a modular architecture by allowing dependencies to be injected directly into SwiftUI views and view models. This approach simplifies testing and development by decoupling your app's components.

Table of Contents

  1. Features
  2. Requirements
  3. Installation
  4. Setup
  5. Usage
  6. Examples
  7. Author

Features

  • Type-Safe Dependencies: Utilize Swift's type system to ensure that your dependencies are correctly resolved at compile time.
  • SwiftUI Integration: Designed with SwiftUI in mind, it seamlessly integrates into the SwiftUI lifecycle and environment.
  • Observability: Supports the injection of observable objects, allowing your views to react dynamically to changes in your dependencies.
  • Ease of Use: Simplify the management of your app's dependencies with minimal boilerplate code.

Requirements

Platform Minimum Version
iOS 17.0
macOS 14.0
tvOS 17.0
watchOS 10.0

Installation

Swift Package Manager

Swift Package Manager is a tool for managing the distribution of Swift code. It integrates with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

Xcode

To integrate DependencyInjectable into your Xcode project using Xcode 15 or later, follow these steps:

  1. Open your project in Xcode.
  2. Select File > Swift Packages > Add Package Dependency...
  3. Enter the package repository URL:
https://github.com/JamesSedlacek/DependencyInjectable.git
  1. Choose the version rule that makes sense for your project.
  2. Select Add Package.

Package.swift

If you are developing a Swift package or have a project that already uses Package.swift, you can add DependencyInjectable as a dependency:

// swift-tools-version:5.10
import PackageDescription

let package = Package(
    name: "DependencyInjectable",
    dependencies: [
        .package(url: "https://github.com/JamesSedlacek/DependencyInjectable.git", branch: "main")
    ],
    targets: [
        .target(
            name: "YourTargetName",
            dependencies: ["DependencyInjectable"])
    ]
)

Setup

To set up dependency injection for your project, follow these steps:

  1. Define a protocol and implementation for your dependencies.
  2. For each of your dependencies, create a dependency key that conforms to the DependencyKey protocol.
  3. Extend DependencyValues to include your dependencies for easy key path access throughout your application.

Usage

Defining a Service

Define a protocol for your service and an implementation:

protocol ExampleServiceable {
    var someProperty: String { get }
}

struct ExampleService: ExampleServiceable {
    let someProperty = "Wow it works!"
}

Creating a Dependency Key

Define a key for your service in the dependency container:

struct ExampleServiceKey: DependencyKey {
    static var defaultValue: ExampleServiceable = ExampleService()
}

Extending DependencyValues

Extend DependencyValues for dot notation access to your service:

extension DependencyValues {
    var exampleService: ExampleServiceable {
        get { self[ExampleServiceKey.self] }
        set { self[ExampleServiceKey.self] = newValue }
    }
}

Updating or removing dependencies from the environment

@main
struct ExampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .environment(
            \.dependencies.exampleService,
             ExampleService("Testing")
        )
    }
}

Injecting a ViewModel into the environment, with dependencies

@main
struct ExampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .inject(ContentViewModel())
        }
    }
}

Injecting dependencies into a ViewModel

Create a view model that injects your service using the @Observable macro and the DependencyInjectable protocol:
Note - onInject(dependencies:) gets called automatically by the .inject(:) view modifier.

@Observable
final class ContentViewModel: DependencyInjectable {
    var service: ExampleServiceable?

    var someProperty: String {
        service?.someProperty ?? "default value"
    }

    func onInject(dependencies: DependencyValues) {
        service = dependencies.exampleService
    }
}

Using Injected ViewModel in a SwiftUI View

struct ContentView: View {
    @Environment(ContentViewModel.self)
    private var viewModel

    var body: some View {
        Text(viewModel.someProperty)
    }
}

Using a dependency from the environment in a SwiftUI View

struct ContentView: View {
    @Environment(\.dependencies.exampleService)
    private var service

    var body: some View {
        Text(service.someProperty)
    }
}

Author

James Sedlacek, find me on X/Twitter or LinkedIn

dependencyinjectable's People

Contributors

jamessedlacek avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.