gpt4 book ai didi

vapor - 了解如何初始化 Vapor 4 存储库

转载 作者:行者123 更新时间:2023-12-03 16:10:43 28 4
gpt4 key购买 nike

我正在尝试使用存储库模式将一些代码从 Vapor 3 迁移到 Vapor 4。我已经完成了 documentation of this specific pattern来自 Vapor 4 文档,我想我大部分都理解它。
然而,我没有得到的一件事是存储库工厂在 Application 中设置的方式。延期。文档中的示例显示了这一点:

extension Application {
private struct UserRepositoryKey: StorageKey {
typealias Value = UserRepositoryFactory
}

var users: UserRepositoryFactory {
get {
self.storage[UserRepositoryKey.self] ?? .init()
}
set {
self.storage[UserRepositoryKey.self] = newValue
}
}
}
如果我正确地阅读了 getter 方法(我可能不是 - 我远非 Swift 专家), UserRepositoryFactory 的新实例结构将在 app.users 时创建并返回被引用。然而,当时似乎没有 self.storage[UserRepositoryKey.self] 的内容。以任何方式改变。所以如果我碰巧访问了 app.users连续两次,我会收到 2 个不同的实例返回给我和 self.storage[UserRepositoryKey.self]将保持设置为 nil .
在文档中的其余示例代码之后,它似乎定义了 make工厂在配置应用程序时将使用的功能:
app.users.use { req in
DatabaseUserRepository(database: req.db)
}
这里看起来像 app.users.use会得到一个新的工厂实例并调用它的 use设置适当的函数 make该实例的方法。
后来,当我去处理一个请求时,我使用 request.usersRequest 定义的方法延期:
extension Request {
var users: UserRepository {
self.application.users.make!(self)
}
}
这里看起来像 self.application.users.make将在 self.application.users 引用的不同存储库工厂实例上调用.因此,它不会应用之前在配置应用程序时设置的工厂的 make 方法。
那么我在这里错过了什么?

最佳答案

看起来文档有点过时了。您可以查看 View 或客户端是如何完成的,但您需要在某个地方调用 initialize()设置存储库。这是我的工作存储库的样子:

import Vapor

extension Application {
struct Repositories {

struct Provider {
let run: (Application) -> ()

public init(_ run: @escaping (Application) -> ()) {
self.run = run
}
}

final class Storage {
var makeRepository: ((Application) -> APIRepository)?
init() { }
}

struct Key: StorageKey {
typealias Value = Storage
}

let application: Application

var repository: APIRepository {
guard let makeRepository = self.storage.makeRepository else {
fatalError("No repository configured. Configure with app.repositories.use(...)")
}
return makeRepository(self.application)
}

func use(_ provider: Provider) {
provider.run(self.application)
}

func use(_ makeRepository: @escaping (Application) -> APIRepository) {
self.storage.makeRepository = makeRepository
}

func initialize() {
self.application.storage[Key.self] = .init()
}

private var storage: Storage {
if self.application.storage[Key.self] == nil {
self.initialize()
}
return self.application.storage[Key.self]!
}
}

var repositories: Repositories {
.init(application: self)
}
}
它在第一次使用时自动初始化。请注意 APIRepository是用于我的存储库的协议(protocol)。 FluentRepository是该协议(protocol)的流畅实现。然后像你一样,我在请求上有一个扩展,可以在请求处理程序中使用它:
extension Request {
var repository: APIRepository {
self.application.repositories.repository.for(self)
}
}
最后,您需要对其进行配置以使用正确的存储库。所以在我的 配置.swift 我有:
app.repositories.use { application in
FluentRepository(database: application.db)
}
在测试中,我可以将它切换为不接触数据库的内存存储库:
application.repositories.use { _ in
return inMemoryRepository
}

关于vapor - 了解如何初始化 Vapor 4 存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63333118/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com