PKSDependencyEngine is a lightweight and efficient dependency injection framework designed specifically for Swift developers. In modern application development, managing dependencies in a clean, maintainable, and testable way is crucial. PKSDependencyEngine simplifies this process by providing an easy-to-use API for registering and resolving dependencies, whether you’re working with classes or protocols.
By integrating PKSDependencyEngine into your project, you can achieve a more modular and decoupled codebase, making it easier to manage complex applications. The framework is thread-safe, ensuring that your dependencies are accessed consistently across different parts of your application without introducing any concurrency issues. Moreover, PKSDependencyEngine has no external dependencies, making it a seamless addition to any Swift project without adding unnecessary bloat.
Whether you're building a small SwiftUI app or a large-scale enterprise application, PKSDependencyEngine provides the flexibility and power you need to manage your dependencies effectively.
- Lightweight and Efficient: Minimal footprint with maximum impact on your dependency management, designed to work smoothly in any Swift project.
- Easy-to-Use API: Intuitive interface for registering and resolving dependencies with minimal boilerplate code.
- Supports Both Class and Protocol-Based Dependencies: Flexibility to use concrete classes or protocols, enabling more testable and decoupled code.
- Thread-Safe: Safely resolve dependencies from multiple threads with no risk of race conditions or unexpected behavior.
- No External Dependencies: PKSDependencyEngine is self-contained, ensuring it integrates cleanly into your project without bringing in additional libraries.
- Lazy Loading: Dependencies are resolved lazily, meaning they are only created when they are accessed for the first time.
- Non-Destroyable Dependencies: Ability to mark certain dependencies as non-destroyable, preventing accidental removal.
To start using PKSDependencyEngine in your project, follow these simple steps:
First, integrate PKSDependencyEngine into your project using Swift Package Manager.
- Open your project in Xcode.
- Navigate to File > Add Packages.
- Enter the repository URL:
https://github.com/ohk/PKSDependencyEngine
. - Select the version and add the package to your project.
If you're using a Package.swift
file, add PKSDependencyEngine as a dependency:
dependencies: [
.package(url: "https://github.com/ohk/PKSDependencyEngine", from: "1.0.0")
]
Registering dependencies is straightforward with PKSDependencyEngine.
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class App {
@PKSRegisterDependency var myDependency: MyDependency = MyDependency()
}
In this example, MyDependency
is registered as a dependency within the App
class.
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class App {
let myDependency: MyDependency = PKSDependencyEngine.shared.register(MyDependency(), for: MyDependency.self)
}
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class App {
let myDependency: MyDependency = PKSDependencyEngine.shared.registerLazy { MyDependency() } for: MyDependency.self)
}
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class App {
let myDependency: MyDependency = PKSDependencyEngine.shared.register(MyDependency(), for: MyDependency.self)
PKSDependencyEngine.shared.addNonDestroyableDependency(for: MyDependency.self)
}
To resolve and use your registered dependencies, simply use the @PKSDependency
property wrapper:
import PKSDependencyEngine
class MyService {
@PKSDependency var dependency: MyDependency
func doSomething() {
dependency.doSomething()
}
}
In this example, MyService
automatically resolves and uses the MyDependency
instance registered earlier.
class MyService {
let dependency: MyDependency = PKSDependencyEngine.shared.read(for: MyDependency.self)
}
You can also register and resolve protocol-based dependencies to promote more flexible and testable code:
import PKSDependencyEngine
protocol MyDependencyProtocol {
func doSomething()
}
class MyDependency: MyDependencyProtocol {
func doSomething() {
print("Doing something...")
}
}
class App {
@PKSRegisterDependency var myDependency: MyDependencyProtocol = MyDependency()
}
class MyService {
@PKSDependency var dependency: MyDependencyProtocol
func doSomething() {
dependency.doSomething()
}
}
With dependencies registered and resolved, you're ready to run your project. PKSDependencyEngine will ensure that your dependencies are managed efficiently, allowing you to focus on building great features.
You can integrate PKSDependencyEngine into your project using Swift Package Manager.
In Xcode, open your project and navigate to File > Add Packages. Enter the repository URL: https://github.com/ohk/PKSDependencyEngine Select the version and add the package to your project. Alternatively, you can add the following dependency to your Package.swift file:
dependencies: [
.package(url: "https://github.com/ohk/PKSDependencyEngine", from: "1.0.0")
]
To register a dependency, use the @PKSRegisterDependency
property wrapper. You can specify the type of the dependency as the generic parameter. For example:
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class App {
@PKSRegisterDependency var myDependency: MyDependency = MyDependency()
...
}
To read a dependency, use the @PKSDependency
property wrapper. You can specify the type of the dependency as the generic parameter. For example:
import PKSDependencyEngine
class MyDependency {
func doSomething() {
print("Doing something...")
}
}
class MyService {
@PKSDependency var dependency: MyDependency
func doSomething() {
dependency.doSomething()
}
...
}
You can also use protocols to define dependencies. For example:
import PKSDependencyEngine
protocol MyDependencyProtocol {
func doSomething()
}
class MyDependency: MyDependencyProtocol {
func doSomething() {
print("Doing something...")
}
}
class MyService {
// Read the dependency
@PKSDependency var dependency: MyDependencyProtocol
func doSomething() {
dependency.doSomething()
}
...
}
class App {
// Register a dependency
@PKSRegisterDependency var myDependency: MyDependencyProtocol = MyDependency()
...
}
To register a dependency, use the @PKSRegisterDependency
property wrapper. To read a dependency, use the @PKSDependency
property wrapper. Dependencies are resolved lazily, meaning they are only created when they are accessed for the first time.
PKSDependencyEngine is thread-safe, meaning you can safely access dependencies from multiple threads without worrying about
PKSDependencyEngine makes it easy to mock dependencies for testing. You can register mock dependencies in your test setup and use them to replace the real dependencies during testing. For example:
import PKSDependencyEngine
class MyDependencyMock: MyDependencyProtocol {
func doSomething() {
print("Mocking something...")
}
}
class MyServiceTests: XCTestCase {
var myService: MyService!
override func setUp() {
super.setUp()
PKSDependencyEngine.shared.clearDependencies()
// Register the mock dependency
PKSDependencyEngine.shared.register(MyDependencyProtocol.self, MyDependencyMock())
myService = MyService()
}
func testDoSomething() {
myService.doSomething()
}
...
}
If you have any ideas for improvements or new features, feel free to open an issue or submit a pull request. Your feedback is highly appreciated!
PKSDependencyEngine is available under the MIT license. See the LICENSE file for more info.
PKSDependencyEngine is developed by Ömer Hamid Kamışlı.