一个支持多实例注册的dicont
22 May 2023
一个支持多实例注册的DIContainer
class DIContainer {
private var registry: [String: Any] = [:]
func register<T>(_ type: T.Type, name: String? = nil, factory: @escaping () -> T) {
let key = "\(type)\(name ?? "")"
registry[key] = factory
}
func resolve<T>(_ type: T.Type, name: String? = nil) -> T? {
let key = "\(type)\(name ?? "")"
return (registry[key] as? () -> T)?()
}
}
使用
protocol MyProtocol {
func doSomething()
}
class MyClass1: MyProtocol {
func doSomething() {
print("MyClass1 did something")
}
}
class MyClass2: MyProtocol {
func doSomething() {
print("MyClass2 did something")
}
}
// 注册并使用
let container = DIContainer()
container.register(MyProtocol.self, name: "instance1") { MyClass1() }
container.register(MyProtocol.self, name: "instance2") { MyClass2() }
let instance1 = container.resolve(MyProtocol.self, name: "instance1")
instance1?.doSomething() // Output: "MyClass1 did something"
let instance2 = container.resolve(MyProtocol.self, name: "instance2")
instance2?.doSomething() // Output: "MyClass2 did something"
用swift写下个DIContainer, 支持类似java中的注解注册,并支持对不同的实现指定不同name.
ChatGPT 回答:
当然,我可以帮你编写一个支持类似Java中的注解注册的DI容器,并且支持为不同的实现指定不同的名称。在Swift中,我们可以使用属性包装器和反射来实现这个功能。
首先,我们需要定义一个DIContainer类,它将负责注册和解析依赖项。我们可以使用一个字典来存储注册的依赖项,其中键是依赖项的名称,值是依赖项的类型。
class DIContainer {
private var dependencies: [String: Any] = [:]
func register<T>(_ type: T.Type, name: String? = nil) {
let key = name ?? String(describing: T.self)
dependencies[key] = type
}
func resolve<T>(_ type: T.Type, name: String? = nil) -> T? {
let key = name ?? String(describing: T.self)
return dependencies[key] as? T
}
}
接下来,我们可以定义一个属性包装器@Inject,它可以用于将依赖项注入到类的属性中。我们可以使用反射来获取属性的类型,并使用DIContainer来解析相应的依赖项。
@propertyWrapper
struct Inject<T> {
private let name: String?
init(name: String? = nil) {
self.name = name
}
var wrappedValue: T? {
get {
return DIContainer.shared.resolve(T.self, name: name)
}
}
}
现在,我们可以使用@Inject属性包装器来注入依赖项。例如,假设我们有一个UserService类,它依赖于UserRepository接口。
protocol UserRepository {
func getUser() -> String
}
class UserRepositoryImpl: UserRepository {
func getUser() -> String {
return "John Doe"
}
}
class UserService {
@Inject<UserRepository> var userRepository: UserRepository?
func printUserName() {
if let user = userRepository?.getUser() {
print("User: \(user)")
}
}
}
现在,我们可以在DIContainer中注册依赖项,并使用UserService类来解析和使用它们。
let container = DIContainer()
container.register(UserRepositoryImpl.self)
container.register(UserRepository.self, name: "mock") // 注册不同的实现并指定名称
let userService = UserService()
userService.printUserName() // 输出: User: John Doe
// 使用不同的实现
container.register(MockUserRepository.self, name: "mock")
userService.printUserName() // 输出: User: Mock User
这就是一个简单的Swift DI容器的实现,它支持类似Java中的注解注册,并且可以为不同的实现指定不同的名称。当然,这只是一个基本的示例,你可以根据自己的需求进行扩展和改进。希望对你有帮助!
