Skip to content

Commit 5c54c9e

Browse files
author
Mohammed Rokon Uddin
authored
Merge pull request #18 from rokon-uddin/repository_segregation
chore: refactor repository to separate interfaces that the repository…
2 parents b6a161d + b9aa4c0 commit 5c54c9e

File tree

9 files changed

+105
-61
lines changed

9 files changed

+105
-61
lines changed

{{cookiecutter.app_name}}/Domain/Sources/Domain/Interface/Repository.swift

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,60 @@
88

99
import Foundation
1010

11-
public protocol Repository {
11+
public protocol PrepareRepository {
12+
func prepare() async throws
13+
}
14+
15+
public protocol CreateRepository {
1216
associatedtype CreateInput = Never
1317
associatedtype CreateOutput = Never
18+
associatedtype RepositoryType
19+
20+
func create(input: CreateInput) async throws -> CreateOutput
21+
static var live: RepositoryType { get }
22+
static var stubbed: RepositoryType { get }
23+
}
24+
25+
public protocol ReadRepository {
1426
associatedtype ReadInput = Never
1527
associatedtype ReadOutput = Never
28+
associatedtype RepositoryType
29+
30+
func read(input: ReadInput) async throws -> ReadOutput
31+
static var live: RepositoryType { get }
32+
static var stubbed: RepositoryType { get }
33+
}
34+
35+
public protocol ReadAllRepository {
36+
associatedtype ReadInput = Never
37+
associatedtype ReadOutput = Never
38+
associatedtype RepositoryType
39+
40+
func readAll(input: ReadInput) async throws -> [ReadOutput]
41+
static var live: RepositoryType { get }
42+
static var stubbed: RepositoryType { get }
43+
}
44+
45+
public protocol UpdateRepository {
1646
associatedtype UpdateInput = Never
1747
associatedtype UpdateOutput = Never
48+
associatedtype RepositoryType
49+
50+
func update(input: UpdateInput) async throws -> UpdateOutput
51+
static var live: RepositoryType { get }
52+
static var stubbed: RepositoryType { get }
53+
}
54+
55+
public protocol DeleteRepository {
1856
associatedtype DeleteInput = Never
1957
associatedtype DeleteOutput = Never
2058
associatedtype RepositoryType
2159

22-
func prepare() async throws
23-
func create(input: CreateInput) async throws -> CreateOutput
24-
func read(input: ReadInput) async throws -> ReadOutput
25-
func update(input: UpdateInput) async throws -> UpdateOutput
2660
func delete(input: DeleteInput) async throws -> DeleteOutput
27-
2861
static var live: RepositoryType { get }
2962
static var stubbed: RepositoryType { get }
3063
}
64+
65+
public typealias RemoteProductRepository = CreateRepository & ReadRepository
66+
67+
public typealias PersistentProductRepository = CreateRepository & ReadRepository

{{cookiecutter.app_name}}/Domain/Sources/Domain/UseCases/PrepareCoreDataUseCase.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import Foundation
1010

1111
public final class PrepareCoreDataUseCase: UseCase {
1212
var prepare: () async throws -> Void
13-
public init<R: Repository>(repository: R) {
14-
self.prepare =
15-
repository.prepare
13+
public init<R: PrepareRepository>(repository: R) {
14+
self.prepare = repository.prepare
1615
}
1716

1817
public func execute(input: Void) async {

{{cookiecutter.app_name}}/Domain/Sources/Domain/UseCases/ProductUseCase.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ public final class ProductUseCase: UseCase {
1212

1313
var getProduct: (_ input: Int) async throws -> Product?
1414

15-
public init<R: Repository>(repository: R)
15+
public init<R: RemoteProductRepository>(repository: R)
1616
where R.ReadInput == Input, R.ReadOutput == Output {
17-
self.getProduct =
18-
repository.read(input:)
17+
self.getProduct = repository.read(input:)
1918
}
2019

2120
@Sendable public func execute(input: Int) async throws -> Product? {

{{cookiecutter.app_name}}/Domain/Sources/Domain/UseCases/SaveProductUseCase.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
66
// Copyright © {% now 'utc', '%Y' %} {{cookiecutter.company_name}}. All rights reserved.
77
//
88

9-
import Combine
109
import Foundation
1110

1211
public final class SaveProductUseCase: UseCase {
1312
var saveProduct: (_ input: Product) async throws -> Void
1413

15-
public init<R: Repository>(repository: R)
14+
public init<R: PersistentProductRepository>(repository: R)
1615
where R.CreateInput == Input, R.CreateOutput == Output {
17-
self.saveProduct =
18-
repository.create(input:)
16+
self.saveProduct = repository.create(input:)
1917
}
2018

2119
@Sendable public func execute(input: Product) async throws {

{{cookiecutter.app_name}}/Features/Sources/App/AppClient.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,18 @@ extension DependencyValues {
3838

3939
extension AppClient: DependencyKey {
4040
public static var liveValue = AppClient(
41-
PrepareCoreDataUseCase(repository: PersistentRepository.live),
42-
productUseCase: ProductUseCase(repository: NetworkRepository.live),
43-
saveProduct: SaveProductUseCase(repository: PersistentRepository.live))
41+
PrepareCoreDataUseCase(repository: PreparePersistentRepository.live),
42+
productUseCase: ProductUseCase(repository: RemoteProductRepository.live),
43+
saveProduct: SaveProductUseCase(
44+
repository: PersistentProductRepository.live))
4445
public static var testValue = AppClient(
45-
PrepareCoreDataUseCase(repository: PersistentRepository.live),
46-
productUseCase: ProductUseCase(repository: NetworkRepository.stubbed),
47-
saveProduct: SaveProductUseCase(repository: PersistentRepository.live))
46+
PrepareCoreDataUseCase(repository: PreparePersistentRepository.live),
47+
productUseCase: ProductUseCase(repository: RemoteProductRepository.stubbed),
48+
saveProduct: SaveProductUseCase(
49+
repository: PersistentProductRepository.live))
4850
public static var previewValue = AppClient(
49-
PrepareCoreDataUseCase(repository: PersistentRepository.live),
50-
productUseCase: ProductUseCase(repository: PersistentRepository.stubbed),
51-
saveProduct: SaveProductUseCase(repository: PersistentRepository.live))
51+
PrepareCoreDataUseCase(repository: PreparePersistentRepository.live),
52+
productUseCase: ProductUseCase(repository: RemoteProductRepository.stubbed),
53+
saveProduct: SaveProductUseCase(
54+
repository: PersistentProductRepository.live))
5255
}

{{cookiecutter.app_name}}/Features/Sources/App/AppFeature.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Domain
1414
public struct AppFeature: FeatureReducer {
1515

1616
@Dependency(\.appClient) var appClient
17+
1718
public init() {}
1819

1920
public struct State: Equatable, Hashable {

{{cookiecutter.app_name}}/NetworkPlatform/Sources/NetworkPlatform/Repository/NetworkRepository.swift renamed to {{cookiecutter.app_name}}/NetworkPlatform/Sources/NetworkPlatform/Repository/RemoteProductRepository.swift

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,15 @@
88

99
import Domain
1010

11-
public struct NetworkRepository: Repository {
11+
public struct RemoteProductRepository: Domain.RemoteProductRepository {
1212

1313
private let network: AppNetworking
1414

1515
private init(network: AppNetworking) {
1616
self.network = network
1717
}
1818

19-
public func prepare() {
20-
fatalError("Unimplemented")
21-
}
22-
23-
public func create(input: Int) async throws -> Product? {
19+
public func create(input: Product) async throws {
2420
fatalError("Unimplemented")
2521
}
2622

@@ -29,19 +25,11 @@ public struct NetworkRepository: Repository {
2925
.product(id: input),
3026
type: Product.self)
3127
}
32-
33-
public func update(input: Int) async throws -> Product? {
34-
fatalError("Unimplemented")
35-
}
36-
37-
public func delete(input: Int) async throws -> Product? {
38-
fatalError("Unimplemented")
39-
}
4028
}
4129

42-
extension NetworkRepository {
43-
public static var live = NetworkRepository(
30+
extension RemoteProductRepository {
31+
public static var live = RemoteProductRepository(
4432
network: AppNetworking.defaultNetworking())
45-
public static var stubbed = NetworkRepository(
33+
public static var stubbed = RemoteProductRepository(
4634
network: AppNetworking.stubbingNetworking())
4735
}
Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@
88

99
import Domain
1010

11-
public struct PersistentRepository: Repository {
11+
public struct PersistentProductRepository: Domain.PersistentProductRepository {
1212

1313
private let persistenceController: PersistenceController
1414

1515
private init(persistenceController: PersistenceController) {
1616
self.persistenceController = persistenceController
1717
}
1818

19-
public func prepare() async {
20-
do {
21-
try await persistenceController.prepare()
22-
} catch {
23-
fatalError(error.localizedDescription)
24-
}
25-
}
26-
2719
public func create(input: Domain.Product) async throws {
2820
await persistenceController.update(
2921
entityType: Product.self, createIfNil: true
@@ -32,6 +24,7 @@ public struct PersistentRepository: Repository {
3224
$0?.title = input.title
3325
$0?.price = input.price
3426
$0?.image = input.image
27+
//FIXME: may be rating is a reserved keyword.
3528
// $0?.rating = product.rating.toManagedObject(in: persistenceController.container.newBackgroundContext())
3629
$0?.category = input.category
3730
$0?.productDescription = input.description
@@ -42,18 +35,11 @@ public struct PersistentRepository: Repository {
4235
await persistenceController.fetchDomainObject(entityType: Product.self)
4336
}
4437

45-
public func update(input: Int) async throws -> Product? {
46-
fatalError("Unimplemented")
47-
}
48-
49-
public func delete(input: Int) async throws -> Product? {
50-
fatalError("Unimplemented")
51-
}
5238
}
5339

54-
extension PersistentRepository {
55-
public static var live = PersistentRepository(
40+
extension PersistentProductRepository {
41+
public static var live = PersistentProductRepository(
5642
persistenceController: PersistenceController.shared)
57-
public static var stubbed = PersistentRepository(
43+
public static var stubbed = PersistentProductRepository(
5844
persistenceController: PersistenceController.shared)
5945
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// PreparePersistentRepository.swift
3+
// PersistentPlatform
4+
//
5+
// Created by {{ cookiecutter.creator }} on {% now 'utc', '%d/%m/%Y' %}.
6+
// Copyright © {% now 'utc', '%Y' %} {{cookiecutter.company_name}}. All rights reserved.
7+
//
8+
9+
import Domain
10+
import Foundation
11+
12+
public struct PreparePersistentRepository: Domain.PrepareRepository {
13+
14+
private let persistenceController: PersistenceController
15+
16+
init(persistenceController: PersistenceController) {
17+
self.persistenceController = persistenceController
18+
}
19+
20+
public func prepare() async {
21+
do {
22+
try await persistenceController.prepare()
23+
} catch {
24+
fatalError(error.localizedDescription)
25+
}
26+
}
27+
}
28+
29+
extension PreparePersistentRepository {
30+
public static var live = PreparePersistentRepository(
31+
persistenceController: PersistenceController.shared)
32+
}
33+

0 commit comments

Comments
 (0)