为了账号安全,请及时绑定邮箱和手机立即绑定

在 DDD(干净/六边形)架构中处理数据库连接和环境配置

在 DDD(干净/六边形)架构中处理数据库连接和环境配置

Go
慕神8447489 2022-05-18 16:09:57
虽然我掌握了总体思路,但我无法看到管理配置环境和管理数据库连接的最佳实践。意义:如果我有存储库(例如 PostgreSQL),我应该将 NewRepository 函数传递给数据库配置吗?它不会以某种方式对架构原则(维护、可测试性等)产生不利影响吗?我们如何处理 defer db.Close() 之类的事情?我的意思是,我们显然希望它与作用域主函数相关,因此将代码移入存储库“类”是有问题的(除非有办法使用 Context 来做到这一点?)另一方面,在 main 范围内调用 NewRepository,然后让 db 处理它外部的连接感觉有点奇怪。我发现的大多数示例都使用了 main 函数,所以很容易。问题是在使用 DDD(干净/六边形)架构时,您如何正确地做到这一点?特别是这样所有的部分都是“可插入的”,而不必“围绕它”更改代码。下面是我整理的一个例子,这里有没有违反ddd模式的一些原则?还是这些事情实际上是如何完成的?1.我不应该在存储库本身处理延迟 db.Close() 吗?也许使用 Context 我可以将它与主要功能范围相关但在存储库本身内推迟?2. 我真的应该将配置传递到 NewRepository 吗?包/main.go:func main() {    // get configuration stucts via .env file    configuration, err := config.NewConfig()    if err != nil {        panic(err)    }    postgresRepo, err := postgres.NewRepository(configuration.Database)    defer postgresRepo.DB.Close()    myService := autocomplete.NewService(postgresRepo)    handler := rest.NewHandler(myService)    ...    ...    ...}pkg/config/config.go:// Config is a struct that contains configuration variablestype Config struct {    Environment string    Port        string    Database    *Database}// Database is a struct that contains DB's configuration variablestype Database struct {    Host     string    Port     string    User     string    DB       string    Password string}// NewConfig creates a new Config structfunc NewConfig() (*Config, error) {    env.CheckDotEnv()    port := env.MustGet("PORT")    // set default PORT if missing    if port == "" {        port = "3000"    }    return &Config{        Environment: env.MustGet("ENV"),        Port:        port,        Database: &Database{            Host:     env.MustGet("DATABASE_HOST"),            Port:     env.MustGet("DATABASE_PORT"),            User:     env.MustGet("DATABASE_USER"),            DB:       env.MustGet("DATABASE_DB"),            Password: env.MustGet("DATABASE_PASSWORD"),        },    }, nil}
查看完整描述

1 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

不要将数据库配置传递到您的存储库,而是尝试传递数据库连接。例如:


func main() {

    db, err := sql.Open("postgres", "...")

    if err != nil {

        log.Fatal(err)

    }

    defer db.Close()


    repo := postgres.NewAutocompleteRepo(db)

    svc := autocomplete.NewService(repo)

    handler := autocomplete.NewHTTPHandler(svc)

}

这将把连接到存储库之外的数据库的责任留给更容易测试。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信