Dip is a simple Dependency Injection Container.

Overview

Dip

CI Status Version Carthage Compatible License Platform Swift Version Swift Version

Animated Dipping GIF
Photo courtesy of www.kevinandamanda.com

Introduction

Dip is a simple Dependency Injection Container.

It's aimed to be as simple as possible yet provide rich functionality usual for DI containers on other platforms. It's inspired by .NET's Unity Container and other DI containers.

  • You start by creating let container = DependencyContainer() and registering your dependencies, by associating a protocol or type to a factory using container.register { MyService() as Service }.
  • Then you can call container.resolve() as Service to resolve an instance of protocol or type using that DependencyContainer.
  • You can easily use Dip along with Storyboards and Nibs . There is also a code generator that can help to simplify registering new components.
Basic usage
import Dip

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    // Create the container
    private let container = DependencyContainer { container in
    
        // Register some factory. ServiceImp here implements protocol Service
        container.register { ServiceImp() as Service }
    }

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
        
        // Resolve a concrete instance. Container will instantiate new instance of ServiceImp
        let service = try! container.resolve() as Service
    
        ...
    }
}
More sophisticated example
ShakeAnimation { return try! self.resolve(withArguments: view) } } extension ViewController: StoryboardInstantiatable {} //ViewController.swift class ViewController { var animationsFactory: AnimationsFactory? private let _formBehaviour = Injected() var formBehaviour: AuthFormBehaviour? { return _formBehaviour.value } ... } ">
import Dip

class AppDelegate: UIResponder, UIApplicationDelegate {
	private let container = DependencyContainer.configure()
	...
}

//CompositionRoot.swift
import Dip
import DipUI

extension DependencyContainer {

	static func configure() -> DependencyContainer {
		return DependencyContainer { container in 
			unowned let container = container
			DependencyContainer.uiContainers = [container]
		
			container.register(tag: "ViewController") { ViewController() }
			  .resolvingProperties { container, controller in
				  controller.animationsFactory = try container.resolve() as AnimatonsFactory
			}
    
			container.register { AuthFormBehaviourImp(apiClient: $0) as AuthFormBehaviour }
			container.register { container as AnimationsFactory }
			container.register { view in ShakeAnimationImp(view: view) as ShakeAnimation }
			container.register { APIClient(baseURL: NSURL(string: "http://localhost:2368")!) as ApiClient }
		}
	}

}

extension DependencyContainer: AnimationsFactory { 
    func shakeAnimation(view: UIView) -> ShakeAnimation {
        return try! self.resolve(withArguments: view)
    }
}

extension ViewController: StoryboardInstantiatable {}

//ViewController.swift

class ViewController {
    var animationsFactory: AnimationsFactory?

    private let _formBehaviour = Injected<AuthFormBehaviour>()
    
    var formBehaviour: AuthFormBehaviour? {
        return _formBehaviour.value
    }
	...
}

Documentation & Usage Examples

Dip is completely documented and comes with a Playground that lets you try all its features and become familiar with API. You can find it in Dip.xcworkspace.

Note: it may happen that you will need to build Dip framework before playground will be able to use it. For that select Dip scheme and build for iPhone Simulator.

You can find bunch of usage examples and usfull tips in a wiki.

If your are using VIPER architecture - here is VIPER demo app that uses Dip instead of manual dependency injection.

There are also several blog posts that describe how to use Dip and some of its implementation details:

File an issue if you have any question. Pull requests are warmly welcome too.

Features

  • Scopes. Dip supports 5 different scopes (or life cycle strategies): Unique, Shared, Singleton, EagerSingleton, WeakSingleton;
  • Auto-wiring & Auto-injection. Dip can infer your components' dependencies injected in constructor and automatically resolve them as well as dependencies injected with properties.
  • Resolving optionals. Dip is able to resolve constructor or property dependencies defined as optionals.
  • Type forwarding. You can register the same factory to resolve different types implemeted by a single class.
  • Circular dependencies. Dip will be able to resolve circular dependencies if you will follow some simple rules;
  • Storyboards integration. You can easily use Dip along with storyboards and Xibs without ever referencing container in your view controller's code;
  • Named definitions. You can register different factories for the same protocol or type by registering them with tags;
  • Runtime arguments. You can register factories that accept up to 6 runtime arguments (and extend it if you need);
  • Easy configuration & Code generation. No complex containers hierarchy, no unneeded functionality. Tired of writing all registrations by hand? There is a cool code generator that will create them for you. The only thing you need is to annotate your code with some comments.
  • Weakly typed components. Dip can resolve "weak" types when they are unknown at compile time.
  • Thread safety. Registering and resolving components is thread safe;
  • Helpful error messages and configuration validation. You can validate your container configuration. If something can not be resolved at runtime Dip throws an error that completely describes the issue;

Installation

You can install Dip using your favorite dependency manager:

CocoaPods

pod "Dip"

Carthage
github "AliSoftware/Dip"

To build for Swift 2.3 run Carthage with --toolchain com.apple.dt.toolchain.Swift_2_3 option.

Swift Package Manager
.Package(url: "https://github.com/AliSoftware/Dip", majorVersion: 5, minor: 0)

Running tests

On OSX you can run tests from Xcode. On Linux you need to have Swift Package Manager installed and use it to build and run tests using this command: swift build --clean && swift build && swift test

Credits

This library has been created by Olivier Halligon and is maintained by Ilya Puchka.

Dip is available under the MIT license. See the LICENSE file for more info.

The animated GIF at the top of this README.md is from this recipe on the yummy blog of Kevin & Amanda. Go try the recipe!

The image used as the SampleApp LaunchScreen and Icon is from Matthew Hine and is under CC-by-2.0.

Comments
  • Auto-injection

    Auto-injection

    This PR adds auto-injection feature.

    What is auto-injection

    Auto-injection is a feature that let's user to get all dependencies (properties) injected by container automatically without calling resolve for each dependency.

    Why we need this

    • It's a more convenient way to define circular dependencies
    • It will enable automatic injection of dependencies for objects created by storyboards or nibs (as I currently imagine possible implementation of that feature) what I think is a very important feature to adopt Dip in real life projects.

    How it works

    This implementation provides not completely automatic resolution which seems to be impossible to implement in Swift without using ObjC runtime. So to inject dependencies user needs:

    • wrap properties with special wrappers to indicate that they should be injected by container
    • obtain an instance of object to inject to (either create it manually or resolve with container)
    • call resolveDependencies method of container and pass it this instance

    resolveDependencies method uses reflection to inspect types of properties. To work around different issues, like initial nil values of properties, weak references and others we use simple wrapper classes: Injected<T> and InjectedWeak<T>. Using Mirror we iterate over properties and pick up those of type Injected or InjectedWeak (actually dummy internal protocols). Then we use resolve and assign resolved instance to values wrapped by those properties. The fact that Injected and InjectedWeak are classes makes it possible to change wrapped value not only in the mirror, but also in reflected object cause values of mirror children are copied by reference as any class in Swift (though Apple does not document this behavior of Mirror with all the possible consequences).

    To be able to resolve this wrapped values for each definition registered with nil tag and block-factory that does not accept runtime arguments we register two additional definitions for Any and AnyObject type (for strong and weak properties correspondingly) associated with special tags. Those tags are just string descriptions of type being registered wrapped in Injected or InjectedWeak. Using such tags makes it possible to distinguish those accessory definitions, cause they all resolve Any or AnyObject types. User will likely not use such tags so there should be no collisions.

    Drawbacks

    • Using wrappers requires some boilerplate code. The same can be done using resolveDependencies method of DefinitionOf. But using auto-injection registration syntax looks much cleaner. Also I think that Injected and InjectedWeak wrappers serve as a developer's documentation to indicate that those properties will be injected at runtime, so developer does not need to go to the point where all registration is performed. Other frameworks like Typhoon also use similar approach.
    • Apple does not document Mirror enough to be sure that required behavior (referencing to child values instead of coping) will not change in future. And actually they already changed reflection API (but not the behavior I believe) between Swift 1.2 and Swift 2.0. But this behavior looks logical and reflection is a language feature, not an OS, so we will be able to adapt (or disable) this feature on demand in later Swift releases.

    Example

    protocol Server {
      weak var client: Client? {get}
    }
    
    protocol Client: class {
      var server: Server? {get}
    }
    
    class ServerImp: Server {
    
      private var _client = InjectedWeak<Client>()
    
      weak var client: Client? {
        return _client.value
      }
    }
    
    class ClientImp: Client {
    
      private var _server = Injected<Server>()
    
      var server: Server? {
        return _server.value
      }
    }
    
    container.register(.ObjectGraph) { ServerImp() as Server }
    container.register(.ObjectGraph) { ClientImp() as Client }
    
    let client = container.resolve() as Client
    
    Core 
    opened by ilyapuchka 32
  • Swift 3 issues

    Swift 3 issues

    Checked on Xcode 8 beta 4

    • [x] Resolving an instance that has weak properties that are not NSObject subclasses causes a crash. https://bugs.swift.org/browse/SR-2144 Workaround: make your weak properties subclasses of NSObject or do not use weak property attribute.
    • [x] Resolving an instance that has IUO properties causes a crash. https://bugs.swift.org/browse/SR-2282 Workaround: use optional properties instead of IUO properties in instances resolved by container.
    • [ ] Container is not able to use factories registered with IUO runtime arguments. https://bugs.swift.org/browse/SR-2143 Workaround: do not use IUO as argument type when registering and resolving components
    • [ ] Swift compiler may generate warnings when using auto-injection (#139) https://bugs.swift.org/browse/SR-2921
    • [ ] Swift does not correctly distinguishes between functions accepting single tuple parameter and functions accepting several parameters of tuple elements types, leading to wrong register method calls (see #147 for details). Should be fixed for Swift 4 with SE-0110
    opened by ilyapuchka 17
  • Allow for creating instances in the container right after it is initialized

    Allow for creating instances in the container right after it is initialized

    This is mostly about the Singleton scope. In many cases, the "create and preserve after first resolve was made" approach can cause various issues, especially if some of these singletons would use events/signals for communication. To provide more flexibility, it would be great to provide a way for singletons to be created and preserved right away and not waiting for first resolve reference. This could be configured per singleton or as a general Dip property.

    enhancement 
    opened by sebastian-zarzycki-apzumi 15
  • Need a way to know when all dependencies are resolved

    Need a way to know when all dependencies are resolved

    Most solid IoC containers provide some form of notification after the object that has some dependencies, has the dependencies resolved.

    If I set up my dependencies like so:

    container = DependencyContainer { container in
      container.register(.Singleton) { LoginService() }
      container.register(.Singleton) { LoginModel() } .resolveDependencies { container, entity in
         entity.loginService = try! container.resolve() as LoginService
      }
    }
    

    I need a way to determine within Login Model when loginService is resolved in, because I might need to instantly operate on it for some reason. I cannot do this in initializer, because loginService isn't injected yet. In theory, I could call a method within the resolveDependencies block, but that doesn't feel like an elegant solution. Does Dip provide/could provide something like this?

    opened by sebastian-zarzycki-apzumi 14
  • Rename a few things.

    Rename a few things.

    Given the Swift API design guidelines, I would like to propose renaming a couple of things in Dip.

    DependencyContainer(configBlock:) should be DependencyContainer(configuration:) or DependencyContainer(configurationBlock:). The old initializer could be transitioned to a convenience init that delegates to the new one, and marked as deprecated. (Avoid abbreviations.)

    resolve(withArguments:) should become either resolve(arguments arguments:) or resolveWithArguments(_:). The old function should be deprecated and delegate to the new one. (When the first argument forms part of a prepositional phrase, give it an argument label.)

    enhancement 
    opened by calebd 13
  • register function is broken in Swift 4

    register function is broken in Swift 4

    Hello, and thanks for Dip, I've been using it for quite a while and I love it so far.

    Today I updated my project to Swift 4 and I found out that some container.register { ... } calls cannot be resolved by the compiler.

    container.register { TestClass($0) } // Works fine
    container.register { TestClass() } // Nope
    

    The error shown is Ambiguous use of 'register(_:type:tag:factory:)'. I guess because of this change, when the register function is used and no argument is ever used inside the closure, the compiler won't be able to choose between all the 0, 1, 2, 3... args register functions in RuntimeArguments.swift.

    As far as I know you still haven't updated the library to work with Swift 4, but I just wanted to report this so it's a known issue for future versions.

    opened by jmartinesp 12
  • Auto resolve Closures which return Registered Types

    Auto resolve Closures which return Registered Types

    Hey, Dip is amazing, and I think its the best DI framework there for swift.

    I found that one can register closures types in Dip, naturally I was wondering whether something like this is possible.

    struct AType {
        let service: String
        let runtime: Int
    }
    
    struct BType {
        let aCreator: (Int) -> AType
        let service: String
    }
    

    Suppose I do this

    let container = DependencyContainer() { c in
        c.register() {
            "Hello" // This resolves to x as its only string registered
        }
        c.register() {
            AType(service: $0, runtime: $1) // as we don't have runtime Int registered we can resolve it as runtime argument
        }
        c.register() {
            BType(aCreator: $0, service: $1) // This fails as $0 is a closure type which is not registered
        }
    }
    

    Can we make closures that return a registered type to auto resolve as closures taking runtime arguments?

    I mean

    (Int) -> AType

    should auto resolve to

     { (a: Int) in try! c.resolve(argument: a) as AType  }
    

    That is if we don't find a closure type registered in container, we check return type of closure, and resolve with arguments for inputs of the closure.

    I haven't dived into Mirror yet, so if you think this is possible, I will look into it and give a pull request, or atleast write a extension for personal use. :)

    opened by sai-prasanna 12
  • Circular dependencies

    Circular dependencies

    This PR adds support for circular dependencies. That feature and using resolve inside factory block requires recursion, but lock around resolve method causes deadlock. I removed locking completely and propose to managed thread safety on client side.

    opened by ilyapuchka 12
  • Don't know how to really share a .shared scope object

    Don't know how to really share a .shared scope object

    Hi,

    I want to share the same instance of a view model between 2 view controllers. But I don't know how to inject it in them without call resolve() function that "reinit" my view model object instance according to this

    Here, part of my Dip container:

    self.register(.singleton) { try Repository(graphQL: self.resolve(), fileStorage: self.resolve()) as RepositoryProtocol }
    self.register(.shared, tag: "SharedVM") { try SharedViewModel(repository: self.resolve()) as SharedViewModelProtocol }
    self.register(storyboardType: AViewController.self, tag: "A")
        .resolvingProperties { container, vc in
            vc.viewModel = try container.resolve(tag: "SharedVM") as SharedViewModelProtocol
        }
    self.register(storyboardType: BViewController.self, tag: "B")
        .resolvingProperties { container, vc in
            vc.viewModel = try container.resolve(tag: "SharedVM") as SharedViewModelProtocol
        }
    

    When I load my AViewController, Dip logs:

    Trying to resolve AViewController with UI container at index 0
    Optional(Context(key: type: AViewController, arguments: (), tag: String("A"), injectedInType: nil, injectedInProperty: nil logErrors: true))
    Optional(Context(key: type: SharedViewModel, arguments: (), tag: String("SharedVM"), injectedInType: AViewController, injectedInProperty: nil logErrors: true))
    Reusing previously resolved instance Repository
    Resolved type SharedViewModelProtocol with SharedViewModel
    Resolved type AViewController with <AViewController: 0x157dbcae0>
    Resolved AViewController
    

    Then when I push my BViewController from AViewController, Dip logs:

    Trying to resolve BViewController with UI container at index 0
    Optional(Context(key: type: BViewController, arguments: (), tag: String("B"), injectedInType: nil, injectedInProperty: nil logErrors: true))
    Optional(Context(key: type: SharedViewModel, arguments: (), tag: String("SharedVM"), injectedInType: BViewController, injectedInProperty: nil logErrors: true))
    Reusing previously resolved instance Repository
    Resolved type SharedViewModelProtocol with SharedViewModel // here, I want Reusing previously resolved instance SharedViewModel
    Resolved type BViewController with <BViewController: 0x157e58a60>
    Resolved BViewController
    

    I don't want to update the view model scope to .singleton because it is not: just a "shared" object for a determinated time

    Thanks for helping me

    question 
    opened by Narayane 11
  • Resolving dependencies and inheritance

    Resolving dependencies and inheritance

    I've think I've encountered somewhat unusual bug/design consequence in Dip:

    code
    
    class BaseModel: Resolvable {
        var baseService: BaseService!
    
        func didResolveDependencies() {
        }
    }
    
    class ChatModel : BaseModel {    
        var chatService: ChatServiceProtocol!
    }
    
    container:
    
    container = DependencyContainer { container in
        let baseService = BaseService()
        container.register(.Singleton) { baseService as BaseService }
    
        let chatService = ChatService()
        container.register(.Singleton) { chatService as ChatServiceProtocol }
    
        let baseModel = BaseModel()
        container.register(.Singleton) { baseModel }.resolveDependencies { container, entity in
            entity.baseService = try! container.resolve() as BaseService
        }
    
        let chatModel = ChatModel()
        container.register(.Singleton) { chatModel }.resolveDependencies { container, entity in
            entity.chatService = try! container.resolve() as ChatServiceProtocol
        }
    }
    

    When I initialize ChatModel somewhere, its baseService is not injected, even though it inherits from BaseModel.

    let chatModel:ChatModel = ChatModel()
    chatModel.chatService // ok
    chatModel.baseService // nil
    

    So it would seem that if objects inherit from other objects, then the properties from inherited object aren't resolved properly, because container doesn't trigger it's process in this case. My goal, was, obviously, to have a ChatModel, that would have both baseService and chatService injected, but I wanted to keep baseService in BaseModel. Did I do something wrong? Is it a bug?

    I do realize, that I could initialize chatModel like so:

    let chatModel = ChatModel()
    container.register(.Singleton) { chatModel }.resolveDependencies { container, entity in
        entity.baseService = try! container.resolve() as BaseService
        entity.chatService = try! container.resolve() as ChatServiceProtocol
    }
    

    But that's (overall) not the point of having inheritance in the first place.

    enhancement help wanted question 
    opened by sebastian-zarzycki-apzumi 11
  • Resolve singleton to multiply interfaces?

    Resolve singleton to multiply interfaces?

    Is it possible to use singleton to resolve different interfaces

    class ServiceImp {}
    extension ServiceImp : SomeService {}
    extension ServiceImp : AnotherService {}
    
    let container = ...
    container.register(.Singleton) { ServiceImp() as SomeService }
    container.register(.Singleton) { ServiceImp() as AnotherService }
    

    Probably we could use next:

    let service = ServiceImp()
    container.register(.Singleton) { service as SomeService }
    container.register(.Singleton) { service as AnotherService }
    

    But does it makes sense?

    question 
    opened by Koshub 11
  • Bump tzinfo from 1.2.5 to 1.2.10

    Bump tzinfo from 1.2.5 to 1.2.10

    Bumps tzinfo from 1.2.5 to 1.2.10.

    Release notes

    Sourced from tzinfo's releases.

    v1.2.10

    TZInfo v1.2.10 on RubyGems.org

    v1.2.9

    • Fixed an incorrect InvalidTimezoneIdentifier exception raised when loading a zoneinfo file that includes rules specifying an additional transition to the final defined offset (for example, Africa/Casablanca in version 2018e of the Time Zone Database). #123.

    TZInfo v1.2.9 on RubyGems.org

    v1.2.8

    • Added support for handling "slim" format zoneinfo files that are produced by default by zic version 2020b and later. The POSIX-style TZ string is now used calculate DST transition times after the final defined transition in the file. The 64-bit section is now always used regardless of whether Time has support for 64-bit times. #120.
    • Rubinius is no longer supported.

    TZInfo v1.2.8 on RubyGems.org

    v1.2.7

    • Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
    • Fixed warnings when running on Ruby 2.8. #112.

    TZInfo v1.2.7 on RubyGems.org

    v1.2.6

    • Timezone#strftime('%s', time) will now return the correct number of seconds since the epoch. #91.
    • Removed the unused TZInfo::RubyDataSource::REQUIRE_PATH constant.
    • Fixed "SecurityError: Insecure operation - require" exceptions when loading data with recent Ruby releases in safe mode.
    • Fixed warnings when running on Ruby 2.7. #106 and #111.

    TZInfo v1.2.6 on RubyGems.org

    Changelog

    Sourced from tzinfo's changelog.

    Version 1.2.10 - 19-Jul-2022

    Version 1.2.9 - 16-Dec-2020

    • Fixed an incorrect InvalidTimezoneIdentifier exception raised when loading a zoneinfo file that includes rules specifying an additional transition to the final defined offset (for example, Africa/Casablanca in version 2018e of the Time Zone Database). #123.

    Version 1.2.8 - 8-Nov-2020

    • Added support for handling "slim" format zoneinfo files that are produced by default by zic version 2020b and later. The POSIX-style TZ string is now used calculate DST transition times after the final defined transition in the file. The 64-bit section is now always used regardless of whether Time has support for 64-bit times. #120.
    • Rubinius is no longer supported.

    Version 1.2.7 - 2-Apr-2020

    • Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
    • Fixed warnings when running on Ruby 2.8. #112.

    Version 1.2.6 - 24-Dec-2019

    • Timezone#strftime('%s', time) will now return the correct number of seconds since the epoch. #91.
    • Removed the unused TZInfo::RubyDataSource::REQUIRE_PATH constant.
    • Fixed "SecurityError: Insecure operation - require" exceptions when loading data with recent Ruby releases in safe mode.
    • Fixed warnings when running on Ruby 2.7. #106 and #111.
    Commits
    • 0814dcd Fix the release date.
    • fd05e2a Preparing v1.2.10.
    • b98c32e Merge branch 'fix-directory-traversal-1.2' into 1.2
    • ac3ee68 Remove unnecessary escaping of + within regex character classes.
    • 9d49bf9 Fix relative path loading tests.
    • 394c381 Remove private_constant for consistency and compatibility.
    • 5e9f990 Exclude Arch Linux's SECURITY file from the time zone index.
    • 17fc9e1 Workaround for 'Permission denied - NUL' errors with JRuby on Windows.
    • 6bd7a51 Update copyright years.
    • 9905ca9 Fix directory traversal in Timezone.get when using Ruby data source
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump cocoapods-downloader from 1.2.2 to 1.6.3

    Bump cocoapods-downloader from 1.2.2 to 1.6.3

    Bumps cocoapods-downloader from 1.2.2 to 1.6.3.

    Release notes

    Sourced from cocoapods-downloader's releases.

    1.6.3

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.2

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.1

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.0

    Enhancements
    • None.
    Bug Fixes
    • Adds a check for command injections in the input for hg and git.
      orta #124

    1.5.1

    Enhancements
    • None.
    Bug Fixes
    • Fix "can't modify frozen string" errors when pods are integrated using the branch option
      buju77 #10920

    1.5.0

    ... (truncated)

    Changelog

    Sourced from cocoapods-downloader's changelog.

    1.6.3 (2022-04-01)

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.2 (2022-03-28)

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.1 (2022-03-23)

    Enhancements
    • None.
    Bug Fixes
    • None.

    1.6.0 (2022-03-22)

    Enhancements
    • None.
    Bug Fixes
    • Adds a check for command injections in the input for hg and git.
      orta #124

    1.5.1 (2021-09-07)

    Enhancements
    • None.

    ... (truncated)

    Commits
    • c03e2ed Release 1.6.3
    • f75bccc Disable Bazaar tests due to macOS 12.3 not including python2
    • 52a0d54 Merge pull request #128 from CocoaPods/validate_before_dl
    • d27c983 Ensure that the git pre-processor doesn't accidentally bail also
    • 3adfe1f [CHANGELOG] Add empty Master section
    • 591167a Release 1.6.2
    • d2564c3 Merge pull request #127 from CocoaPods/validate_before_dl
    • 99fec61 Switches where we check for invalid input, to move it inside the download fun...
    • 96679f2 [CHANGELOG] Add empty Master section
    • 3a7c54b Release 1.6.1
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Definitions lookup with lazy operator

    Definitions lookup with lazy operator

    I find out that optionals definitions lookup was made by combination of filter + isEmpty. The problem with that approach is that it's iterate definitions until the end even when the target elements stored at the begin. This behavior can be optimized using the contains operator.

    opened by AgranatMarkit 0
  • Inconsistent Crash while resolving

    Inconsistent Crash while resolving

    We're seeing a crash in DIP when creating the initial view controller which through it's references winds up trying to resolve a type which results in a crash. This type can be described as such (using made-up names to simplify):

    struct Configuration {}
    
    protocol Foo {}
    
    open class SuperClass: Foo {
       var configsByUser: [String: Configuration] = []
    }
    
    class SubClass: SuperClass {}
    

    We register SubClass into the dependency container using the type Foo. When we resolve, there seems to be a crash at https://github.com/AliSoftware/Dip/blob/0193aa6bf6151f7ecd88ff26dba6c0525c3eabd6/Sources/AutoInjection.swift#L48

    In this specific case it seems to be trying to deal with the property configsByUser above. In the debugger I am able to see the following:

    (lldb) po type(of: child.value)
    Swift.Dictionary<Swift.String, Configuration>
    

    It seems that the data in the Mirror is neither AutoInjectedPropertyBox nor ImplicitlyUnwrappedOptional. Accessing child.value at all seems to crash as the debugger cannot do anything with it beyond querying the type as far as I can tell. I saw https://bugs.swift.org/browse/SR-2282 that you filed but that doesn't seem to be the same issue.

    I'm unsure if this shows a problem with how things are registered or what but I wasn't sure how to chase this further. Any input would be greatly appreciated as this error happens very frequently in the simulator which is destroying our automated testing. We do not think we've seen this at all on an actual device so that could be another data point.

    opened by SlashDevSlashGnoll 4
  • Thread safety question

    Thread safety question

    Hi,

    enable thread sanitiser in Xcode.

    I used the sample app provided and added this code. in application didFinishLaunchingWithOptions after the configure function.

                DispatchQueue.global(qos: .userInteractive).async {
                    _ = try! self.container.resolve() as PersonProviderAPI
                }
    

    i am getting the error below

    (lldb) thread info -s
    thread #1: tid = 0xb5feba, 0x000000010846d210 libclang_rt.tsan_iossim_dynamic.dylib`__tsan_on_report, queue = 'com.apple.main-thread', stop reason = Data race detected
    
    {
      "all_addresses_are_same" : true,
      "description" : "Data race",
      "instrumentation_class" : "ThreadSanitizer",
      "is_swift_access_race" : false,
      "issue_type" : "data-race",
      "location_description" : "Location is a 144-byte heap object at 0x7b24000196b0",
      "locs" : [
        {
          "address" : 0,
          "file_descriptor" : 0,
          "index" : 0,
          "object_type" : "",
          "size" : 144,
          "start" : 135394549143216,
          "suppressable" : 0,
          "thread_id" : 1,
          "trace" : [
            4433745643,
            4518380009,
            4432193247,
            4432193580,
            4480071751,
            4547030401
          ],
          "type" : "heap"
        }
      ],
      "memory_address" : 135394549143240,
      "mops" : [
        {
          "address" : 135394549143240,
          "index" : 0,
          "is_atomic" : false,
          "is_write" : true,
          "size" : 8,
          "thread_id" : 1,
          "trace" : [
            4455414645,
            4455417239,
            4455399549,
            4455413244,
            4455496011,
            4455490104,
            4455489180,
            4455488196,
            4432186403,
            4432192140,
            4480034918,
            4547030401
          ]
        },
        {
          "address" : 135394549143240,
          "index" : 1,
          "is_atomic" : false,
          "is_write" : false,
          "size" : 8,
          "thread_id" : 3,
          "trace" : [
            4455495051,
            4455490104,
            4455489180,
            4455488196,
            4432190235,
            4432190546,
            4432190881,
            4433864684,
            4546520124
          ]
        }
      ],
      "mutexes" : [
        {
          "address" : 135360189314752,
          "destroyed" : 0,
          "index" : 0,
          "mutex_id" : 1138,
          "trace" : [
            4433615524,
            4456469052,
            4455387904,
            4455395834,
            4455395015,
            4432193247,
            4432193580,
            4480071751,
            4547030401
          ]
        }
      ],
      "report_count" : 0,
      "sleep_trace" : [
    
      ],
      "stacks" : [
    
      ],
      "stop_description" : "Data race detected",
      "summary" : "Data race in closure #1 () throws -> A in Dip.DependencyContainer.inContext<A>(key: Dip.DefinitionKey, injectedInType: Swift.Optional<Any.Type>, injectedInProperty: Swift.Optional<Swift.String>, inCollaboration: Swift.Bool, container: Swift.Optional<Dip.DependencyContainer>, logErrors: Swift.Optional<Swift.Bool>, block: () throws -> A) throws -> A at 0x7b24000196b0",
      "tag" : 0,
      "threads" : [
        {
          "index" : 0,
          "name" : "",
          "parent_thread_id" : 1,
          "running" : 1,
          "thread_id" : 1,
          "thread_os_id" : 11927226,
          "trace" : [
    
          ]
        },
        {
          "index" : 1,
          "name" : "",
          "parent_thread_id" : 0,
          "running" : 1,
          "thread_id" : 3,
          "thread_os_id" : 11927348,
          "trace" : [
    
          ]
        }
      ],
      "unique_tids" : [
    
      ]
    }
    
    
    file:///Users/or84489/ws/Dip/Sources/Dip.swift: runtime: Threading Issues: Data race in closure #1 () throws -> A in Dip.DependencyContainer.inContext<A>(key: Dip.DefinitionKey, injectedInType: Swift.Optional<Any.Type>, injectedInProperty: Swift.Optional<Swift.String>, inCollaboration: Swift.Bool, container: Swift.Optional<Dip.DependencyContainer>, logErrors: Swift.Optional<Swift.Bool>, block: () throws -> A) throws -> A at 0x7b24000196b0
    
    notice: Threading Issues: Location is a 144-byte heap object at 0x7b24000196b0
    
    Write of size 8 by thread 1
    #0	0x0000000109903b75 in closure #1 in DependencyContainer.inContext<A>(key:injectedInType:injectedInProperty:inCollaboration:container:logErrors:block:) at /Users/or84489/ws/Dip/Sources/Dip.swift:233
    #1	0x0000000109904597 in partial apply for closure #1 in DependencyContainer.inContext<A>(key:injectedInType:injectedInProperty:inCollaboration:container:logErrors:block:) ()
    #2	0x000000010990007d in DependencyContainer.threadSafe<A>(_:) at /Users/or84489/ws/Dip/Sources/Dip.swift:109
    #3	0x00000001099035fc in DependencyContainer.inContext<A>(key:injectedInType:injectedInProperty:inCollaboration:container:logErrors:block:) at /Users/or84489/ws/Dip/Sources/Dip.swift:208
    #4	0x000000010991794b in DependencyContainer._resolve(type:tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:141
    #5	0x0000000109916238 in DependencyContainer.resolve(_:tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:123
    #6	0x0000000109915e9c in DependencyContainer._resolve<A>(tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:131
    #7	0x0000000109915ac4 in DependencyContainer.resolve<A>(tag:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:50
    #8	0x00000001082dcc23 in AppDelegate.application(_:didFinishLaunchingWithOptions:) at /Users/or84489/ws/Dip/SampleApp/DipSampleApp/AppDelegate.swift:31
    #9	0x00000001082de28c in @objc AppDelegate.application(_:didFinishLaunchingWithOptions:) ()
    #10	0x000000010b07e866 in -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] ()
    #11	0x000000010f062d81 in start ()
    Read of size 8 by thread 3
    #0	0x000000010991758b in DependencyContainer._resolve(type:tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:141
    #1	0x0000000109916238 in DependencyContainer.resolve(_:tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:123
    #2	0x0000000109915e9c in DependencyContainer._resolve<A>(tag:builder:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:131
    #3	0x0000000109915ac4 in DependencyContainer.resolve<A>(tag:) at /Users/or84489/ws/Dip/Sources/Resolve.swift:50
    #4	0x00000001082ddb1b in closure #1 in AppDelegate.application(_:didFinishLaunchingWithOptions:) at /Users/or84489/ws/Dip/SampleApp/DipSampleApp/AppDelegate.swift:28
    #5	0x00000001082ddc52 in partial apply for closure #1 in AppDelegate.application(_:didFinishLaunchingWithOptions:) ()
    #6	0x00000001082ddda1 in thunk for @escaping @callee_guaranteed () -> () ()
    #7	0x00000001084767ec in __tsan::invoke_and_release_block(void*) ()
    #8	0x000000010efe643c in _dispatch_client_callout ()
    Heap block allocated by thread 1
    #0	0x00000001084596eb in wrap_malloc ()
    #1	0x000000010d5101e9 in swift_slowAlloc ()
    #2	0x00000001082de6df in AppDelegate.init() at /Users/or84489/ws/Dip/SampleApp/DipSampleApp/AppDelegate.swift:17
    #3	0x00000001082de82c in @objc AppDelegate.init() ()
    #4	0x000000010b087847 in _UIApplicationMainPreparations ()
    #5	0x000000010f062d81 in start ()
    Mutex M1138 created
    #0	0x0000000108439aa4 in wrap_pthread_mutex_init ()
    #1	0x0000000109a0523c in -[NSRecursiveLock init] ()
    #2	0x00000001098fd300 in NSRecursiveLock.__allocating_init() ()
    #3	0x00000001098ff1fa in DependencyContainer.init(autoInjectProperties:configBlock:) at /Users/or84489/ws/Dip/Sources/Dip.swift:46
    #4	0x00000001098feec7 in DependencyContainer.__allocating_init(autoInjectProperties:configBlock:) ()
    #5	0x00000001082de6df in AppDelegate.init() at /Users/or84489/ws/Dip/SampleApp/DipSampleApp/AppDelegate.swift:17
    #6	0x00000001082de82c in @objc AppDelegate.init() ()
    #7	0x000000010b087847 in _UIApplicationMainPreparations ()
    #8	0x000000010f062d81 in start ()
    

    please advise

    opened by ofirreuv72 3
Releases(7.1.1)
  • 7.1.1(Dec 27, 2019)

  • 7.1.0(Nov 10, 2019)

    • You can now use a shorthand syntax for resolving a single property using a key path, i.e. resolvingProperty(\.value).
    • Swift 5.0 support (#224).
    • Fixed resolving nested types with the same local names (#221).
    • @Injected and @IntectedWeak property wrappers (#225).
    • Thread safety can be disabled on container level.
    Source code(tar.gz)
    Source code(zip)
  • 7.0.1(Dec 20, 2018)

  • 7.0.0(Sep 22, 2018)

  • 6.0.0(Sep 22, 2018)

  • 5.1(Apr 9, 2017)

  • 5.0.4(Nov 1, 2016)

  • 5.0.3(Oct 23, 2016)

  • 5.0.2(Oct 9, 2016)

  • 5.0.1(Sep 16, 2016)

    This release is the same as 5.0.0 and only fixes CocoaPods speck pushed to trunk without macOS, tvOS and watchOS deployment targets. Please use this release instead of 5.0.0 if you integrate Dip via Cocoapods.

    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Sep 11, 2016)

    New

    • Migrated to Swift 3.0
      #120, @patrick-lind, @mark-urbanthings, @ilyapuchka
    • Renamed DefinitionOf to Definition and some other source-breaking refactoring.
      #113, @ilyapuchka
    • Added invalidType error when resolved instance does not implement requested type.
      #118, @ilyapuchka
    • Added optional type parameter in register methods to be able to specify type when registering using method literal instead of closure. #115, @ilyapuchka
    • Added implements family of methods in to Definition to register type-forwarding definitions.
      #114, @ilyapuchka
    • Shared scope is now the default scope.
      #112, @ilyapuchka
    • Single target project setup.
      #121, @ilyapuchka
    • Simplified implementation of auto-wiring. Container now chooses the definition for type with most number of arguments and does not use other definitions if this one fails to resolve. #117, @ilyapuchka

    Fixed

    • Auto-injected properties inherited from super class are now properly injected when resolving subclass. Added resolveDependencies(_:DependencyContainer) method to Resolvable protocol to handle inheritance when resolving.
      #116, @ilyapuchka
    Source code(tar.gz)
    Source code(zip)
    Dip.framework.zip(7.06 MB)
  • 4.6.1(Aug 14, 2016)

    New

    Fixed

    • Fixed sharing singletons between collaborating containers #103, @ilyapuchka

    Notes on API changes

    All changes are made by adding new API and deprecating old versions. They will be removed in the next release.

    1. ObjectGraph scope is renamed to Shared, Prototype scope is renamed to Unique.
    2. resolveDependencies method of DefinitionOf<T> is renamed to resolvingProperties
    3. DefinitionKey properties protocolType is renamed to type, associatedTag is renamed to tag, argumentsType is renamed to typeOfArguments.
    4. resolve method parameter withArguments is renamed to arguments. That change affects all resolve methods of DependencyContainer
    5. Order of scope and tag parameters in register method is switched. That change affects all register methods of DependencyContainer
    Source code(tar.gz)
    Source code(zip)
    Dip.framework.zip(6.93 MB)
  • 4.6.0(Jul 17, 2016)

    New features

    • Containers collaboration. Break your definitions in modules and link them together.
      #95, @ilyapuchka
    • Added WeakSingleton scope.
      #96, @ilyapuchka
    • Properties auto-injection now is performed before calling resolveDependencies block
      #97, @ilyapuchka
    • Fixed updating container's context when resolving properties with auto-injection.
      #98, @ilyapuchka
    • Improved logging.
      #94, #99, @ilyapuchka
    • Fixed warning about using only extensions api.
      #92, @mwoollard
    Source code(tar.gz)
    Source code(zip)
    Dip.framework.zip(6.57 MB)
  • 4.5.0(Jun 8, 2016)

    New features

    • Added weakly-typed API to resolve components when exact type is unknown during compile time.
      #79, @ilyapuchka
    • Added type forwarding feature. You can register the same factory to resolve different types.
      #89, @ilyapuchka
    • Container now can resolve optional types :tada:
      #84, @ilyapuchka
    • Added container context that provides contextual information during graph resolution process.
      #83, @ilyapuchka
    • Added method to validate container configuration.
      #87, @ilyapuchka
    • Added method to manually set value wrapped by auto-injection wrappers.
      #81, @ilyapuchka
    • Added separate error type for failures during auto-wiring.
      #85, @ilyapuchka

    Note

    With introduction of type-forwarding the behavior of func resolveDependencies(block: (DependencyContainer, T) throws -> ()) -> DefinitionOf<T, F> changed. Now you can call this method several times on the same definition. When instance is resolved using this definition the container will call all the blocks that you passed to this method in the same order as you called this method.

    Source code(tar.gz)
    Source code(zip)
    Dip.framework.zip(5.92 MB)
  • 4.4.0(Mar 31, 2016)

  • 4.3.1(Mar 24, 2016)

  • 4.3.0(Mar 19, 2016)

  • 4.2.0(Mar 19, 2016)

  • 4.1.0(Feb 4, 2016)

  • 4.0.0(Dec 12, 2015)

    New Features

    • Added support for circular dependencies:
      • Added ObjectGraph scope to reuse resolved instances
      • Added resolveDependencies method on DefinitionOf class to resolve dependencies of resolved instance.
        #11, @ilyapuchka
    • Added methods to register/remove individual definitions.
      #11, @ilyapuchka
    • All resolve methods now can throw error if type can not be resolved.
      #15, @ilyapuchka
    • DependencyContainer is marked as final.
    • Added support for OSX, tvOS and watchOS2.
      #26, @ilyapuchka

    Breaking Changes

    • Removed container thread-safety to enable recursion calls to resolve.
      Access to container from multiple threads should be handled by clients from now on.

    • All resolve methods now can throw.

      Note on migration from 3.x to 4.0.0:

      • Errors

      In 4.0.0 each resolve method can throw DefinitionNotFound(DefinitionKey) error, so you need to call it using try! or try?, or catch the error if it's appropriate for your case. See #15 for rationale of this change.

      • Thread safety

      In 4.0.0 DependencyContainer drops any guarantee of thread safety. From now on code that uses Dip must ensure that it's methods are called from a single thread. For example if you have registered type as a singleton and later two threads try to resolve it at the same time you can have two different instances of type instead of one as expected. This change was required to enable recursive calls of resolve method to resolve circular dependencies.

      • Removed methods

      Methods deprecated in 3.1.0 are now removed.

    Source code(tar.gz)
    Source code(zip)
    Dip.framework.zip(2.40 MB)
  • 3.1.0(Dec 12, 2015)

    New

    • Added name for the first runtime argument in resolve(tag:withArguments: … ) methods to make more clear separation between tag and factory runtime arguments.

    Depreciations

    • resolve(tag:_: … ) methods are deprecated in favor of those new resolve(tag:withArguments: … ) methods.
    • Deprecated register(tag:instance:) method in favor of register(.Singleton) { … }.
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Nov 22, 2015)

  • 2.0.0(Nov 22, 2015)

    • Moved from generic tag parameter on container to Tag enum with String and Int cases
      #3, @ilyapuchka

    This API change allows easier use of DependencyContainer and avoid some constraints. For a complete rationale on that change, see PR #3.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Nov 22, 2015)

  • 1.0.0(Nov 22, 2015)

    Dip

    • Added Unit Tests for SWAPIPersonProvider and SWAPIStarshipProvider

    All work in progress is now done. I consider Dip to be ready for production and with a stable API, hence the 1.0.0 version bump.

    Example Project

    • Using func fetchIDs and func fetchOne instead of lazy var for readability
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Nov 22, 2015)

    Dip

    • Dip is now Thread-Safe
    • Added a configuration block so we can easily create the container and register the dependencies all in one expression:
    let deps = DependencyContainer() {
      $0.register() { x as Foo }
      $0.register() { y as Bar }
      $0.register() { z as Baz }
    }
    
    • Source Documentation

    Example Project

    • Code Cleanup
    • Added more values to HardCodedStarshipProvider so it works when the PersonProviderAPI uses real pilots from swapi.co (SWAPIPersonProvider)
    Source code(tar.gz)
    Source code(zip)
  • 0.0.4(Nov 22, 2015)

  • 0.0.3(Nov 22, 2015)

    Example Project

    • Revamped the Sample project to a more complete example (using StarWars API!)
    • Using Mixins & Traits in the Sample App for FetchableTrait and FillableCell
    Source code(tar.gz)
    Source code(zip)
  • 0.0.2(Nov 22, 2015)

    Dip

    • Switched from class methods to instance methods (#1). This allows you to have multiple DependencyContainers
    • Renamed the class from Dependency to DependencyContainer
    • Renamed the instanceFactory: parameter to factory:
    • Made the DependencyContainer generic of the type of tag. We are no longer limited to tags of type String, we can now use anything that's Equatable.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.1(Nov 22, 2015)

    Initial version to release the early proof of concept.

    Ready to use, but API may change, documentation and unit tests are missing, and thread-safety is not guaranteed.

    Source code(tar.gz)
    Source code(zip)
Owner
Olivier Halligon
iOS architect & Swift lover. OSS enthusiast.
Olivier Halligon
ViperServices - Simple dependency injection container for services written for iOS in swift supporting boot order

ViperServices Introduction ViperServices is dependency injection container for iOS applications written in Swift. It is more lightweight and simple in

Siarhei Ladzeika 5 Dec 8, 2022
Deli is an easy-to-use Dependency Injection Container that creates DI containers

Deli is an easy-to-use Dependency Injection Container that creates DI containers with all required registrations and corresponding factories.

Jungwon An 134 Aug 10, 2022
DIContainer Swift is an ultra-light dependency injection container made to help developers to handle dependencies easily. It works with Swift 5.1 or above.

?? DIContainer Swift It is an ultra-light dependency injection container made to help developers to handle dependencies easily. We know that handle wi

Victor Carvalho Tavernari 10 Nov 23, 2022
A new approach to Container-Based Dependency Injection for Swift and SwiftUI.

A new approach to Container-Based Dependency Injection for Swift and SwiftUI. Why do something new? Resolver was my first Dependency Injection system.

Michael Long 573 Jan 2, 2023
Container is a lightweight dependency injection framework for Swift.

Container Container is a lightweight dependency injection framework for Swift. Installation is available in the Swift Package Manager. Swift Package M

Aleksei Artemev 17 Oct 13, 2022
Injection - Dependency injection using property wrappers

Dependency injection using property wrappers. Registering types: // injecting a

Alejandro Ramirez 3 Mar 14, 2022
A simple way to handle dependency injection using property wrappers

Injektion Introduction A simple way to handle dependency injection using propert

Andrew McGee 2 May 31, 2022
StoryboardBuilder - Simple dependency injection for generating views from storyboard.

StoryboardBuilder Simple dependency injection for generating views from storyboard. Description StoryboardBuilder is framework to help simply and easi

null 5 Jun 13, 2019
Injector - A Swift package for simple dependency injection that also supports Swift UI previews

A Swift package for simple dependency injection that also supports Swift UI prev

null 6 Aug 9, 2022
Cleanse is a dependency injection framework for Swift.

Cleanse - Swift Dependency Injection Cleanse is a dependency injection framework for Swift. It is designed from the ground-up with developer experienc

Square 1.7k Dec 16, 2022
Corridor A Coreader-like Dependency Injection μFramework

Corridor A Coreader-like Dependency Injection μFramework Table of Contents Why | Examples | Usage | Installation | Credits & License | Why In order to

symentis GmbH 60 Nov 1, 2022
DIKit Dependency Injection Framework for Swift, inspired by KOIN.

DIKit Dependency Injection Framework for Swift, inspired by KOIN. Basically an implementation of service-locator pattern, living within the applicatio

null 95 Dec 22, 2022
Tranquillity is a lightweight but powerful dependency injection library for swift.

DITranquillity Tranquillity is a lightweight but powerful dependency injection library for swift. The name "Tranquillity" laid the foundation in the b

Ivlev Alexander 393 Dec 24, 2022
Swinject is a lightweight dependency injection framework for Swift.

Swinject Swinject is a lightweight dependency injection framework for Swift. Dependency injection (DI) is a software design pattern that implements In

null 5.6k Dec 31, 2022
Typhoon Powerful dependency injection for Cocoa and CocoaTouch.

Typhoon Powerful dependency injection for Cocoa and CocoaTouch. Lightweight, yet full-featured and super-easy to use. Pilgrim is a pure Swift successo

AppsQuick.ly 2.7k Dec 14, 2022
Dependency Injection framework for Swift (iOS/macOS/Linux)

Declarative, easy-to-use and safe Dependency Injection framework for Swift (iOS/macOS/Linux) Features Dependency declaration via property wrappers or

Scribd 684 Dec 12, 2022
Swift Ultralight Dependency Injection / Service Locator framework

Swift Ultralight Dependency Injection / Service Locator framework

Michael Long 1.9k Jan 6, 2023
Reliant - Nonintrusive Objective-C Dependency Injection

Reliant Reliant is a Dependency Injection (DI) framework for Objective-C, both for OS X and iOS. Its goal is to make its use as simple as possible, wh

AppFoundry 52 Oct 14, 2022
Pilgrim - Dependency injection for Swift (iOS, OSX, Linux). Strongly typed, pure Swift successor to Typhoon.

pilgrim.ph Pilgrim is a dependency injection library for Swift with the following features: Minimal runtime-only library that works with pure Swift (s

AppsQuick.ly 60 Oct 24, 2022