package container import ( "carrotskin/internal/repository" "carrotskin/internal/service" "carrotskin/pkg/auth" "carrotskin/pkg/database" "carrotskin/pkg/email" "carrotskin/pkg/redis" "carrotskin/pkg/storage" "time" "go.uber.org/zap" "gorm.io/gorm" ) // Container 依赖注入容器 // 集中管理所有依赖,便于测试和维护 type Container struct { // 基础设施依赖 DB *gorm.DB Redis *redis.Client Logger *zap.Logger JWT *auth.JWTService Storage *storage.StorageClient CacheManager *database.CacheManager // Repository层 UserRepo repository.UserRepository ProfileRepo repository.ProfileRepository TextureRepo repository.TextureRepository TokenRepo repository.TokenRepository ClientRepo repository.ClientRepository ConfigRepo repository.SystemConfigRepository YggdrasilRepo repository.YggdrasilRepository // Service层 UserService service.UserService ProfileService service.ProfileService TextureService service.TextureService TokenService service.TokenService YggdrasilService service.YggdrasilService VerificationService service.VerificationService UploadService service.UploadService SecurityService service.SecurityService CaptchaService service.CaptchaService } // NewContainer 创建依赖容器 func NewContainer( db *gorm.DB, redisClient *redis.Client, logger *zap.Logger, jwtService *auth.JWTService, storageClient *storage.StorageClient, emailService interface{}, // 接受 email.Service 但使用 interface{} 避免循环依赖 ) *Container { // 创建缓存管理器 cacheManager := database.NewCacheManager(redisClient, database.CacheConfig{ Prefix: "carrotskin:", Expiration: 5 * time.Minute, Enabled: true, }) c := &Container{ DB: db, Redis: redisClient, Logger: logger, JWT: jwtService, Storage: storageClient, CacheManager: cacheManager, } // 初始化Repository c.UserRepo = repository.NewUserRepository(db) c.ProfileRepo = repository.NewProfileRepository(db) c.TextureRepo = repository.NewTextureRepository(db) c.TokenRepo = repository.NewTokenRepository(db) c.ClientRepo = repository.NewClientRepository(db) c.ConfigRepo = repository.NewSystemConfigRepository(db) c.YggdrasilRepo = repository.NewYggdrasilRepository(db) // 初始化SignatureService(用于获取Yggdrasil私钥) signatureService := service.NewSignatureService(c.ProfileRepo, redisClient, logger) // 获取Yggdrasil私钥并创建JWT服务 _, privateKey, err := signatureService.GetOrCreateYggdrasilKeyPair() if err != nil { logger.Fatal("获取Yggdrasil私钥失败", zap.Error(err)) } yggdrasilJWT := auth.NewYggdrasilJWTService(privateKey, "carrotskin") // 初始化Service(注入缓存管理器) c.UserService = service.NewUserService(c.UserRepo, c.ConfigRepo, jwtService, redisClient, cacheManager, logger) c.ProfileService = service.NewProfileService(c.ProfileRepo, c.UserRepo, cacheManager, logger) c.TextureService = service.NewTextureService(c.TextureRepo, c.UserRepo, cacheManager, logger) // 使用JWT版本的TokenService c.TokenService = service.NewTokenServiceJWT(c.TokenRepo, c.ClientRepo, c.ProfileRepo, yggdrasilJWT, logger) // 使用组合服务(内部包含认证、会话、序列化、证书服务) c.YggdrasilService = service.NewYggdrasilServiceComposite(db, c.UserRepo, c.ProfileRepo, c.TokenRepo, c.YggdrasilRepo, signatureService, redisClient, logger) // 初始化其他服务 c.SecurityService = service.NewSecurityService(redisClient) c.UploadService = service.NewUploadService(storageClient) c.CaptchaService = service.NewCaptchaService(redisClient, logger) // 初始化VerificationService(需要email.Service) if emailService != nil { if emailSvc, ok := emailService.(*email.Service); ok { c.VerificationService = service.NewVerificationService(redisClient, emailSvc) } } return c } // NewTestContainer 创建测试用容器(可注入mock依赖) func NewTestContainer(opts ...Option) *Container { c := &Container{} for _, opt := range opts { opt(c) } return c } // Option 容器配置选项 type Option func(*Container) // WithDB 设置数据库连接 func WithDB(db *gorm.DB) Option { return func(c *Container) { c.DB = db } } // WithRedis 设置Redis客户端 func WithRedis(redis *redis.Client) Option { return func(c *Container) { c.Redis = redis } } // WithLogger 设置日志 func WithLogger(logger *zap.Logger) Option { return func(c *Container) { c.Logger = logger } } // WithJWT 设置JWT服务 func WithJWT(jwt *auth.JWTService) Option { return func(c *Container) { c.JWT = jwt } } // WithStorage 设置存储客户端 func WithStorage(storage *storage.StorageClient) Option { return func(c *Container) { c.Storage = storage } } // WithUserRepo 设置用户仓储 func WithUserRepo(repo repository.UserRepository) Option { return func(c *Container) { c.UserRepo = repo } } // WithProfileRepo 设置档案仓储 func WithProfileRepo(repo repository.ProfileRepository) Option { return func(c *Container) { c.ProfileRepo = repo } } // WithTextureRepo 设置材质仓储 func WithTextureRepo(repo repository.TextureRepository) Option { return func(c *Container) { c.TextureRepo = repo } } // WithTokenRepo 设置令牌仓储 func WithTokenRepo(repo repository.TokenRepository) Option { return func(c *Container) { c.TokenRepo = repo } } // WithConfigRepo 设置系统配置仓储 func WithConfigRepo(repo repository.SystemConfigRepository) Option { return func(c *Container) { c.ConfigRepo = repo } } // WithUserService 设置用户服务 func WithUserService(svc service.UserService) Option { return func(c *Container) { c.UserService = svc } } // WithProfileService 设置档案服务 func WithProfileService(svc service.ProfileService) Option { return func(c *Container) { c.ProfileService = svc } } // WithTextureService 设置材质服务 func WithTextureService(svc service.TextureService) Option { return func(c *Container) { c.TextureService = svc } } // WithTokenService 设置令牌服务 func WithTokenService(svc service.TokenService) Option { return func(c *Container) { c.TokenService = svc } } // WithYggdrasilRepo 设置Yggdrasil仓储 func WithYggdrasilRepo(repo repository.YggdrasilRepository) Option { return func(c *Container) { c.YggdrasilRepo = repo } } // WithYggdrasilService 设置Yggdrasil服务 func WithYggdrasilService(svc service.YggdrasilService) Option { return func(c *Container) { c.YggdrasilService = svc } } // WithVerificationService 设置验证码服务 func WithVerificationService(svc service.VerificationService) Option { return func(c *Container) { c.VerificationService = svc } } // WithUploadService 设置上传服务 func WithUploadService(svc service.UploadService) Option { return func(c *Container) { c.UploadService = svc } } // WithSecurityService 设置安全服务 func WithSecurityService(svc service.SecurityService) Option { return func(c *Container) { c.SecurityService = svc } } // WithCaptchaService 设置验证码服务 func WithCaptchaService(svc service.CaptchaService) Option { return func(c *Container) { c.CaptchaService = svc } }