https://github.com/alschmut/factorydependencyinjection
Dependency Injection with Factory
https://github.com/alschmut/factorydependencyinjection
Last synced: 11 months ago
JSON representation
Dependency Injection with Factory
- Host: GitHub
- URL: https://github.com/alschmut/factorydependencyinjection
- Owner: alschmut
- Created: 2024-02-13T11:00:06.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-13T11:38:08.000Z (over 2 years ago)
- Last Synced: 2024-12-27T18:23:27.340Z (over 1 year ago)
- Language: Swift
- Size: 15.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Dependency Injection with Factory
To decouple the dependency injection framework [Factory](https://github.com/hmlongco/Factory) from the internal app usage there are two options:
## Using KeyPaths to access a defined service on one of possibly many containers
### Service Usage
```swift
class MyViewModel {
private let myService: MyServiceProtocol
init(
myService: any MyServiceProtocol = resolve(\.myService)
) {
self.myService = myService
}
}
```
### Service definition
```swift
protocol MyServiceProtocol {
func getSomething() -> String
}
extension FactoryContainer {
var myService: FactoryAdapter {
FactoryAdapter { MyService() }
}
}
struct MyService: MyServiceProtocol {
func getSomething() -> String {
return ""
}
}
```
### FactoryAdapter
```swift
func resolve(_ factoryAdapter: KeyPath>) -> Value {
FactoryContainer.shared[keyPath: factoryAdapter]()
}
struct FactoryContainer {
static let shared = FactoryContainer()
}
struct FactoryAdapter {
let factory: Factory
init(
value: @escaping () -> Value
) {
factory = Factory(Container.shared) { value() }
}
init(
scope: FactoryScope,
value: @escaping () -> Value
) {
factory = Factory(Container.shared) { value() }.scope(Self.scope(from: scope))
}
func callAsFunction() -> Value {
factory()
}
private static func scope(from scope: FactoryScope) -> Scope {
switch scope {
case .singleton: return .singleton
case .cashed: return .cached
case .shared: return .shared
}
}
}
enum FactoryScope {
case singleton
case cashed
case shared
}
```
## Using static variables on a single global container
### Service Usage
```swift
class MyViewModel {
private let myService: MyServiceProtocol
init(
myService: any MyServiceProtocol = resolve(.myService)
) {
self.myService = myService
}
}
```
### Service definition
```swift
protocol MyServiceProtocol {
func getSomething() -> String
}
extension FactoryAdapter {
static let myService = FactoryAdapter {
MyService()
}
}
struct MyService: MyServiceProtocol {
func getSomething() -> String {
return ""
}
}
```
### FactoryAdapter
```swift
func resolve(_ factoryAdapter: FactoryAdapter) -> Value {
factoryAdapter()
}
struct FactoryAdapter {
let factory: Factory
init(
value: @escaping () -> Value
) {
factory = Factory(Container.shared) { value() }
}
init(
scope: FactoryScope,
value: @escaping () -> Value
) {
factory = Factory(Container.shared) { value() }.scope(Self.scope(from: scope))
}
func callAsFunction() -> Value {
factory()
}
private static func scope(from scope: FactoryScope) -> Scope {
switch scope {
case .singleton: return .singleton
case .cashed: return .cached
case .shared: return .shared
}
}
}
enum FactoryScope {
case singleton
case cashed
case shared
}
```