uber/needle
Needle is a dependency injection (DI) system for Swift. Unlike other DI frameworks, such as [Cleanse](https://github.com/square/Cleanse), [Swinject](https://github.com/Swinject/Swinject), Needle encourages **hierarchical DI structure and utilizes code generation to ensure compile
The gist
Using Needle to write DI code for your application is easy and compile-time safe. Each dependency scope is defined by a Component. And its dependencies are encapsulated in a Swift protocol. The two are linked together using Swift generics.
/// This protocol encapsulates the dependencies acquired from ancestor scopes.
protocol MyDependency: Dependency {
/// These are objects obtained from ancestor scopes, not newly introduced at this scope.
var chocolate: Food { get }
var milk: Food { get }
}
/// This class defines a new dependency scope that can acquire dependencies from ancestor scopes
/// via its dependency protocol, provide new objects on the DI graph by declaring properties,
/// and instantiate child scopes.
class MyComponent: Component<MyDependency> {
/// A new object, hotChocolate, is added to the dependency graph. Child scope(s) can then
/// acquire this via their dependency protocol(s).
var hotChocolate: Drink {
return HotChocolate(dependency.chocolate, dependency.milk)
}
/// A child scope is always instantiated by its parent(s) scope(s).
var myChildComponent: MyChildComponent {
return MyChildComponent(parent: self)
}
}This is pretty much it, when writing DI code with Needle. As you can see, everything is real, compilable Swift code. No fragile comments or "annotations". To quickly recap, the three key concepts here are dependency protocol, component and instantiation of child component(s). Please refer to the Getting started with Needle section below for more detailed explanations and advanced topics.
Getting started with Needle
Using and integrating with Needle has two steps. Each of the following steps has detailed instructions and explanations in the linked documents.
Installation
Needle has two parts, the NeedleFoundation framework and the executable code generator. Both parts need to be integrated with your Swift project in order to use Needle as your DI system.
Install NeedleFoundation framework
Using Carthage
Please follow the standard Carthage installation process to integrate the NeedleFoundation framework with your Swift project.
github "https://github.com/uber/needle.git" ~> VERSION_OF_NEEDLEUsing Swift Package Manager
Please specify Needle as a dependency via the standard Swift Package Manager package definition process to integrate the NeedleFoundation framework with your Swift project.
dependencies: [
.package(url: "https://github.com/uber/needle.git", .upToNextMajor(from: "VERSION_NUMBER")),
],
targets: [
.target(
name: "YOUR_MODULE",
dependencies: [
"NeedleFoundation",
]),
],Using CocoaPods
Please follow the standard pod integration process and use NeedleFoundation pod.
Install code generator
Using Carthage
If Carthage is used to integrate the NeedleFoundation framework, then a copy of the code generator executable of the corresponding version is already downloaded in the Carthage folder. It can be found at Carthage/Checkouts/needle/Generator/bin/needle.
Using Homebrew
Regardless of how the NeedleFoundation framework is integrated into your project, the generator can always be installed via Homebrew.
brew install needle[Why use dependency injection?](./WHY_DI.md)
The linked document uses a somewhat real example to explain what the dependency injection pattern is, and its benefits.
Translations
License
[[FOSSA Status]](https://app.fossa.io/projects/git%2Bgithub.com%2Fuber%2Fswift-concurrency?ref=badge_large)
Package Metadata
Repository: uber/needle
Default branch: master
README: README.md