Skip to content

Commit 2c9b04c

Browse files
committed
commit: add ModuleRoute
1 parent e57acc8 commit 2c9b04c

File tree

10 files changed

+446
-61
lines changed

10 files changed

+446
-61
lines changed

.gitignore

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,8 @@
1-
# Xcode
2-
#
3-
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4-
5-
## User settings
1+
.DS_Store
2+
/.build
3+
/Packages
64
xcuserdata/
7-
8-
## Obj-C/Swift specific
9-
*.hmap
10-
11-
## App packaging
12-
*.ipa
13-
*.dSYM.zip
14-
*.dSYM
15-
16-
## Playgrounds
17-
timeline.xctimeline
18-
playground.xcworkspace
19-
20-
# Swift Package Manager
21-
#
22-
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
23-
# Packages/
24-
# Package.pins
25-
# Package.resolved
26-
# *.xcodeproj
27-
#
28-
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
29-
# hence it is not needed unless you have added a package configuration file to your project
30-
# .swiftpm
31-
32-
.build/
33-
34-
# CocoaPods
35-
#
36-
# We recommend against adding the Pods directory to your .gitignore. However
37-
# you should judge for yourself, the pros and cons are mentioned at:
38-
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
39-
#
40-
# Pods/
41-
#
42-
# Add this line if you want to avoid checking in source code from the Xcode workspace
43-
# *.xcworkspace
44-
45-
# Carthage
46-
#
47-
# Add this line if you want to avoid checking in source code from Carthage dependencies.
48-
# Carthage/Checkouts
49-
50-
Carthage/Build/
51-
52-
# fastlane
53-
#
54-
# It is recommended to not store the screenshots in the git repo.
55-
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
56-
# For more information about the recommended setup visit:
57-
# https://docs.fastlane.tools/best-practices/source-control/#source-control
58-
59-
fastlane/report.xml
60-
fastlane/Preview.html
61-
fastlane/screenshots/**/*.png
62-
fastlane/test_output
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

Package.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// swift-tools-version: 5.10.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "ModuleRoute",
8+
products: [
9+
// Products define the executables and libraries a package produces, making them visible to other packages.
10+
.library(
11+
name: "ModuleRoute",
12+
targets: ["ModuleRoute"]),
13+
],
14+
targets: [
15+
// Targets are the basic building blocks of a package, defining a module or a test suite.
16+
// Targets can depend on other targets in this package and products from dependencies.
17+
.target(
18+
name: "ModuleRoute"),
19+
.testTarget(
20+
name: "ModuleRouteTests",
21+
dependencies: ["ModuleRoute"]
22+
),
23+
]
24+
)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// DependencyContainer.swift
3+
// ModuleRoute
4+
//
5+
// Created by GIKI on 2025/2/13.
6+
//
7+
8+
import Foundation
9+
10+
public typealias DependencyFactory = () -> Any
11+
12+
public protocol DependencyContainer {
13+
func register<T>(dependencyFactory: @escaping DependencyFactory, forType type: T.Type)
14+
func resolve<T>(_ type: T.Type) -> T?
15+
}
16+
17+
public class DefaultDependencyContainer: DependencyContainer {
18+
19+
private var factories = [String: DependencyFactory]()
20+
private var instances = [String: Any]()
21+
22+
public init() {}
23+
24+
public func register<T>(dependencyFactory: @escaping DependencyFactory, forType type: T.Type) {
25+
let key = "\(type)"
26+
factories[key] = dependencyFactory
27+
}
28+
29+
public func resolve<T>(_ type: T.Type) -> T? {
30+
let key = "\(type)"
31+
// 检查是否已有实例
32+
if let instance = instances[key] as? T {
33+
return instance
34+
}
35+
36+
// 使用工厂创建新实例
37+
if let factory = factories[key] {
38+
let instance = factory()
39+
instances[key] = instance
40+
return instance as? T
41+
}
42+
43+
return nil
44+
}
45+
}

Sources/ModuleRoute/MRInject.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// Inject.swift
3+
// ModuleRoute
4+
//
5+
// Created by GIKI on 2025/2/13.
6+
//
7+
8+
import Foundation
9+
10+
@propertyWrapper
11+
public class MRInject<T>: Resolvable {
12+
private var dependency: T?
13+
public var wrappedValue: T {
14+
guard let dependency = dependency else {
15+
fatalError("Dependency \(T.self) not resolved")
16+
}
17+
return dependency
18+
}
19+
20+
public init() {}
21+
22+
public func resolve(using container: DependencyContainer) {
23+
dependency = container.resolve(T.self)
24+
}
25+
}
26+
27+
28+
public protocol Resolvable {
29+
func resolve(using container: DependencyContainer)
30+
}
31+

Sources/ModuleRoute/MRModule.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Module.swift
3+
// ModuleRoute
4+
//
5+
// Created by GIKI on 2025/2/13.
6+
//
7+
8+
import UIKit
9+
10+
public protocol MRModule {
11+
func build(from route: MRRoute?) -> UIViewController
12+
func resolveDependencies(using container: DependencyContainer)
13+
func isEnabled(route: MRRoute?) -> Bool
14+
func fallbackModule(for route: MRRoute?) -> MRModule.Type?
15+
init()
16+
}
17+
18+
extension MRModule {
19+
20+
public func resolveDependencies(using container: DependencyContainer) {
21+
let mirror = Mirror(reflecting: self)
22+
for child in mirror.children {
23+
if let resolvable = child.value as? Resolvable {
24+
resolvable.resolve(using: container)
25+
}
26+
}
27+
}
28+
29+
public func isEnabled(route: MRRoute?) -> Bool { return true }
30+
public func fallbackModule(for route: MRRoute?) -> MRModule.Type? { return nil }
31+
}
32+

0 commit comments

Comments
 (0)