{"id":19188801,"url":"https://github.com/miquido/mqdo","last_synced_at":"2025-05-08T02:47:13.055Z","repository":{"id":39636299,"uuid":"434545088","full_name":"miquido/MQDo","owner":"miquido","description":"Swift features management and dependency injection framework. The project was made by Miquido: https://www.miquido.com/","archived":false,"fork":false,"pushed_at":"2024-06-13T09:20:50.000Z","size":180,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-20T06:35:01.007Z","etag":null,"topics":["dependency-injection","ios","ipados","macos","swift","tvos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miquido.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-12-03T09:51:52.000Z","updated_at":"2024-06-13T09:06:38.000Z","dependencies_parsed_at":"2024-11-09T11:38:18.258Z","dependency_job_id":null,"html_url":"https://github.com/miquido/MQDo","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miquido%2FMQDo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miquido%2FMQDo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miquido%2FMQDo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miquido%2FMQDo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miquido","download_url":"https://codeload.github.com/miquido/MQDo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252989940,"owners_count":21836665,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","ios","ipados","macos","swift","tvos","watchos"],"created_at":"2024-11-09T11:26:04.696Z","updated_at":"2025-05-08T02:47:13.039Z","avatar_url":"https://github.com/miquido.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MQDo\n\n[![Platforms](https://img.shields.io/badge/platform-iOS%20|%20iPadOS%20|%20macOS-gray.svg?style=flat)]()\n[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)\n[![SwiftVersion](https://img.shields.io/badge/Swift-5.7-brightgreen.svg)]()\n\nDependency injection framework for Swift.\n\n## Features\n\nMQDo provides numerous functionalities useful for managing dependencies across Swift codebases:\n- dependency container tree with support for branches and scopes\n- scopes with automatic access and lifetime management\n- multiple dependency trees (multiple, independent tree roots)\n- multiple implementations of the same type within a single tree based on scopes\n- multiple instances of the same type within a single tree based on scopes\n- dynamic implementation selection\n- nested dependencies\n- cache and lazy loading\n- effortless mocking and testing\n- error diagnostics\n\n## Example\n\nBasic example of a container, feature definition and feature access.\n\nFirstly you have to prepare feature interface. All interfaces should be defined using structs. \nIt helps in both testing (mocking) and debugging. Using structs instead of protocols is also \nrequired due to swift compiler limitations in some cases.\n\n```swift\n\n// Interface of a feature prepared using a struct.\nstruct Printer {\n\n  // Method required by the interface\n  var printMessage: (String) -\u003e Void\n}\n```\n\nThen define its conformance to a required protocol allowing usage in dependency containers.\nDepending on selected protocol it also defines a lifetime and accessibility of a feature.\n`StaticFeature` is always available and have to be defined. `DisposableFeature` is built\neach time instance is requested returning fresh instance each time. `CacheableFeature` is built\nonce for defined scope, cached and reused when able.\n\n```swift\n\n// Conformance to one of a \"Feature\" protocols is required. \n// Dynamic features (Disposable, Cacheable) can have a Context defined or be contextless (which is default).\n// Context is then required to create instances and can be used to pass any additional data and methods inside.\nextension Printer: DisposableFeature {\n\n  // It is required to provide placeholder implementation.\n  // Placeholders are then used as a base for mocking.\n  static var placeholder: Self {\n    .init(\n      printMessage: unimplemented1()\n    )\n  }\n}\n```\n\nNext you can provide any number of implementations. You can do it ad-hoc (as in example below) or by using \nonly a concrete type which will be used to fulfill interface requirements.\n\n```swift\n\n// Implementation of a feature can be provided by defining\n// FeatureLoader loading instances of given feature.\nextension Printer  {\n\n  static func consolePrinter() -\u003e FeatureLoader {\n    // There are multiple available implementations of the FeatureLoader\n    // which correspond to a lifetime and loading behavior of implemented feature\n    // based on its type.\n    .disposable { (features: Features) -\u003e Printer in\n      // `features` is a container context which can be used\n      // to retrieve any other features if needed.\n      Printer(\n        logMessage: { (message: String) in\n          print(message)\n        }\n      )\n    }\n  }\n}\n```\n\nIf you have defined your feature interface and some implementation you can then register it within a scope inside a container to be available. All feature implementations should be defined when creating container tree root.\n\n```swift\nlet features: Features = FeaturesRoot { (registry: inout FeaturesRegistry\u003cRootFeaturesScope\u003e) in\n  registry.use(.consolePrinter())\n  // you can also define other scopes and its features in this context\n}\n```\n\nFinally you can access any feature from the container.\n\n```swift\nlet printer: Printer = try features.instance()\n```\n\nIf requested feature was not defined in available registry or there was any issue with accessing its instance you will get full diagnostics required to track the error.\n\n```\n⎡ ⚠️ FeatureUndefined\n⎜ 📺 FeatureUndefined\n⎜ 🧵 Context: \n⎜ 📍 MQDo/Example.swift:36\n⎜ ✉️ FeatureUndefined \n⎜ 🧩 feature: Printer\n⎣ ⚠️ FeatureUndefined\n```\n\n## License\n\nCopyright 2021-2023 Miquido\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiquido%2Fmqdo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiquido%2Fmqdo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiquido%2Fmqdo/lists"}