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

虽然我掌握了总体思路,但我无法看到管理配置环境和管理数据库连接的最佳实践。

意义:

  1. 如果我有存储库(例如 PostgreSQL),我应该将 NewRepository 函数传递给数据库配置吗?它不会以某种方式对架构原则(维护、可测试性等)产生不利影响吗?

  2. 我们如何处理 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 variables

type Config struct {

    Environment string

    Port        string

    Database    *Database

}


// Database is a struct that contains DB's configuration variables

type Database struct {

    Host     string

    Port     string

    User     string

    DB       string

    Password string

}


// NewConfig creates a new Config struct

func 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

}


慕神8447489
浏览 108回答 1
1回答

精慕HU

不要将数据库配置传递到您的存储库,而是尝试传递数据库连接。例如: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)}这将把连接到存储库之外的数据库的责任留给更容易测试。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go