虽然我掌握了总体思路,但我无法看到管理配置环境和管理数据库连接的最佳实践。意义:如果我有存储库(例如 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)
}
这将把连接到存储库之外的数据库的责任留给更容易测试。
- 1 回答
- 0 关注
- 107 浏览
添加回答
举报
0/150
提交
取消