An open API service indexing awesome lists of open source software.

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

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
}
```