Dependency injection (DI) is a design pattern that allows components to be loosely coupled by providing their dependencies as arguments. This can make code more modular, reusable, and testable.
The FSDependencyInjection library provides a simple and efficient way to implement DI in Swift.
To install the DependencyInjection library, add the following dependency to your Package.swift file:
dependencies: [
.package(url: "https://github.com/LLCFreedom-Space/fs-dependency-injection.git", from: "1.0.0")
]
To use the DependencyInjection library, you first need to create a Container instance. The shared property provides a shared instance of the container that can be used throughout your application.
let container = Container.shared
Once you have a Container instance, you can register services with it. To register a service, you call the register() method. The register() method takes two arguments: the type of the service to register and a factory closure that creates an instance of the service.
class MyService { ... }
// Use factory
container.register(
to: MyService.self,
factory: { container in
MyService()
}
)
// Or via value
container.register(
to: MyService.self,
value: MyService()
)
The factory closure can access the container to resolve other dependencies.
To resolve a service from the container, you call the resolve() method. The resolve() method takes one argument: the type of the service to resolve.
let myService = container.resolve()
The resolve() method returns an optional value. If the service is not registered, the method returns nil.
The lifetime of a service instance can be either transient or singleton. Transient instances are created anew each time they are resolved. Singleton instances are shared across all requests.
The lifetime of a service instance can be specified when it is registered with the container. The InstanceType
enum defines two cases:
transient
: The service instance is transient.singleton
: The service instance is a singleton.
class MyService { ... }
container.register(
to: MyService.self,
instanceType: .singleton
)
The DependencyInjection
library also provides a property wrapper, @Inject
, that can be used to inject dependencies into properties.
To use the @Inject
property wrapper, you simply annotate the property with the wrapper.
The wrapper will automatically inject the appropriate service instance into the property.
class MyViewController {
@Inject var myService: MyService
}
In this example, the myService property in MyViewController will be injected with a singleton instance of MyService.
Here is an example of how to use the DependencyInjection
library:
class MyService {
var name: String
init(name: String) {
self.name = name
}
}
class MyViewController {
@Inject var myService: MyService
init() {
myService.name = "Hello, world!"
}
func printName() {
print(myService.name)
}
}
let viewController = MyViewController()
viewController.printName()
This code will print the following output:
Hello, world!
LLC Freedom Space – @LLCFreedomSpace – [email protected]
Distributed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3. See LICENSE.md for more information.