refactor: introduce Wire dependency injection and interface-based architecture
- Add Google Wire for compile-time dependency injection - Replace concrete service types with interfaces across handlers - Remove global state (DB, cache) in favor of constructor injection - Split monolithic files into focused modules: - config: separate files for each config domain - dto: converters split by domain (user, post, message, group) - cache: separate metrics.go and redis_cache.go - Introduce unified apperrors package with string-based error codes - Add transaction support with context-aware repository methods - Upgrade golang.org/x/crypto from 0.17.0 to 0.26.0
This commit is contained in:
121
internal/wire/infrastructure.go
Normal file
121
internal/wire/infrastructure.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"carrot_bbs/internal/cache"
|
||||
"carrot_bbs/internal/config"
|
||||
"carrot_bbs/internal/model"
|
||||
"carrot_bbs/internal/pkg/email"
|
||||
"carrot_bbs/internal/pkg/gorse"
|
||||
"carrot_bbs/internal/pkg/openai"
|
||||
"carrot_bbs/internal/pkg/redis"
|
||||
"carrot_bbs/internal/pkg/s3"
|
||||
"carrot_bbs/internal/pkg/sse"
|
||||
"carrot_bbs/internal/repository"
|
||||
|
||||
"github.com/google/wire"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// InfrastructureSet 基础设施 Provider Set
|
||||
var InfrastructureSet = wire.NewSet(
|
||||
// 配置
|
||||
ProvideConfig,
|
||||
|
||||
// 数据库
|
||||
ProvideDB,
|
||||
|
||||
// 事务管理器
|
||||
ProvideTransactionManager,
|
||||
|
||||
// Redis 和缓存
|
||||
ProvideRedisClient,
|
||||
ProvideCache,
|
||||
|
||||
// SSE Hub
|
||||
ProvideSSEHub,
|
||||
|
||||
// 外部服务客户端
|
||||
ProvideGorseClient,
|
||||
ProvideOpenAIClient,
|
||||
ProvideEmailClient,
|
||||
ProvideS3Client,
|
||||
)
|
||||
|
||||
// ProvideConfig 加载配置
|
||||
func ProvideConfig() (*config.Config, error) {
|
||||
return config.Load("configs/config.yaml")
|
||||
}
|
||||
|
||||
// ProvideDB 提供数据库连接
|
||||
func ProvideDB(cfg *config.Config) (*gorm.DB, error) {
|
||||
return model.NewDB(&cfg.Database)
|
||||
}
|
||||
|
||||
// ProvideRedisClient 提供 Redis 客户端
|
||||
func ProvideRedisClient(cfg *config.Config) *redis.Client {
|
||||
client, err := redis.New(&cfg.Redis)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed to connect to Redis: %v, falling back to memory cache", err)
|
||||
return nil
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// ProvideCache 提供缓存实例
|
||||
func ProvideCache(cfg *config.Config, redisClient *redis.Client) cache.Cache {
|
||||
cache.Configure(cache.Settings{
|
||||
Enabled: cfg.Cache.Enabled,
|
||||
KeyPrefix: cfg.Cache.KeyPrefix,
|
||||
DefaultTTL: time.Duration(cfg.Cache.DefaultTTL) * time.Second,
|
||||
NullTTL: time.Duration(cfg.Cache.NullTTL) * time.Second,
|
||||
JitterRatio: cfg.Cache.JitterRatio,
|
||||
PostListTTL: time.Duration(cfg.Cache.Modules.PostList) * time.Second,
|
||||
ConversationTTL: time.Duration(cfg.Cache.Modules.Conversation) * time.Second,
|
||||
UnreadCountTTL: time.Duration(cfg.Cache.Modules.UnreadCount) * time.Second,
|
||||
GroupMembersTTL: time.Duration(cfg.Cache.Modules.GroupMembers) * time.Second,
|
||||
DisableFlushDB: cfg.Cache.DisableFlushDB,
|
||||
})
|
||||
|
||||
// 直接创建 RedisCache 实例,不依赖全局变量
|
||||
if redisClient == nil {
|
||||
log.Println("[Wire] Warning: Redis client is nil, cache will not be available")
|
||||
return nil
|
||||
}
|
||||
|
||||
cacheInstance := cache.NewRedisCache(redisClient)
|
||||
log.Println("[Wire] Initialized Redis cache via dependency injection")
|
||||
return cacheInstance
|
||||
}
|
||||
|
||||
// ProvideSSEHub 提供 SSE Hub
|
||||
func ProvideSSEHub() *sse.Hub {
|
||||
return sse.NewHub()
|
||||
}
|
||||
|
||||
// ProvideGorseClient 提供 Gorse 客户端
|
||||
func ProvideGorseClient(cfg *config.Config) gorse.Client {
|
||||
return gorse.NewClient(gorse.ConfigFromAppConfig(&cfg.Gorse))
|
||||
}
|
||||
|
||||
// ProvideOpenAIClient 提供 OpenAI 客户端
|
||||
func ProvideOpenAIClient(cfg *config.Config) openai.Client {
|
||||
return openai.NewClient(openai.ConfigFromAppConfig(&cfg.OpenAI))
|
||||
}
|
||||
|
||||
// ProvideEmailClient 提供邮件客户端
|
||||
func ProvideEmailClient(cfg *config.Config) email.Client {
|
||||
return email.NewClient(email.ConfigFromAppConfig(&cfg.Email))
|
||||
}
|
||||
|
||||
// ProvideS3Client 提供 S3 客户端
|
||||
func ProvideS3Client(cfg *config.Config) (*s3.Client, error) {
|
||||
return s3.New(&cfg.S3)
|
||||
}
|
||||
|
||||
// ProvideTransactionManager 提供事务管理器
|
||||
func ProvideTransactionManager(db *gorm.DB) repository.TransactionManager {
|
||||
return repository.NewTransactionManager(db)
|
||||
}
|
||||
Reference in New Issue
Block a user