package di import ( "context" "database/sql" "net/http" "time" nice "github.com/ekyoung/gin-nice-recovery" "github.com/gin-gonic/gin" "gin_test/config" "gin_test/event" "gin_test/model" authmod "gin_test/modules/auth" usermod "gin_test/modules/user" "gin_test/pkg/jwt" "gin_test/routes" ) // migrated 表示已完成 DB 初始化迁移。 type migrated struct{} func ProvideMigrated(db *sql.DB) (migrated, error) { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() if err := model.Migrate(ctx, db); err != nil { return migrated{}, err } return migrated{}, nil } type tokenIssueListenerRegistered struct{} func ProvideTokenIssueListener(bus *event.Dispatcher, jwtSvc *jwt.Service) tokenIssueListenerRegistered { authmod.RegisterTokenIssueListener(bus, jwtSvc) return tokenIssueListenerRegistered{} } func ProvideConfig() (config.Config, error) { cfg := config.Load() return cfg, cfg.Validate() } func ProvideJWTSecret(cfg config.Config) string { return cfg.JWT.Secret } func ProvideJWTExpirySeconds(cfg config.Config) int { return cfg.JWT.ExpirySeconds } func ProvideDBConfig(cfg config.Config) config.DBConfig { return cfg.DB } type serverDurations struct { gracefulTimeout time.Duration readHeaderTimeout time.Duration } func ProvideServerDurations(cfg config.Config) serverDurations { gracefulTimeout, readHeaderTimeout := cfg.ServerDuration() return serverDurations{ gracefulTimeout: gracefulTimeout, readHeaderTimeout: readHeaderTimeout, } } func ProvideJWTMiddleware(jwtSvc *jwt.Service, _ tokenIssueListenerRegistered) gin.HandlerFunc { return authmod.JWTMiddleware(jwtSvc) } func ProvideRouter(cfg config.Config, userHandler *usermod.Handler, jwtMiddleware gin.HandlerFunc) *gin.Engine { // gin mode 需要在创建 engine 前生效。 gin.SetMode(cfg.Server.GinMode) r := gin.New() r.Use(gin.Logger()) r.Use(nice.Recovery(recoveryHandler)) routes.RegisterRoutes(r, userHandler, jwtMiddleware) return r } // recoveryHandler 让 panic / unhandled error 都返回统一 JSON。 func recoveryHandler(c *gin.Context, err interface{}) { c.JSON(http.StatusInternalServerError, gin.H{ "code": 500, "message": "服务器内部错误", }) } func ProvideHTTPServer(cfg config.Config, router *gin.Engine, d serverDurations, _ migrated) *http.Server { return &http.Server{ Addr: cfg.Server.Addr, Handler: router, ReadHeaderTimeout: d.readHeaderTimeout, } } func ProvideApp(db *sql.DB, server *http.Server, d serverDurations) *App { return &App{ DB: db, Server: server, GracefulTimeout: d.gracefulTimeout, } }