// container_factory.go package container import ( "log" "sync" "git.x2erp.com/qdy/go-base/config" ) type Resource interface { GetName() string Close() } type CreateFunc[T Resource] func(cfg config.IConfig) T type ContainerFactory struct { config config.IConfig resources map[string]Resource // 用map按名称存储 order []string // 保持添加顺序 mu sync.RWMutex } func NewContainer(cfg config.IConfig) *ContainerFactory { return &ContainerFactory{ config: cfg, resources: make(map[string]Resource), order: make([]string, 0), } } // 泛型方法:如果不存在则创建并注册 func Create[T Resource](c *ContainerFactory, createFunc CreateFunc[T]) T { //c.mu.Lock() //defer c.mu.Unlock() // 先创建对象获取名称 resource := createFunc(c.config) return Reg(c, resource) // name := resource.GetName() // log.Printf("创建 %s 对象", name) // // 如果已存在,返回已注册的对象 // if existing, ok := c.resources[name]; ok { // log.Printf("对象 %s 已经存在.", name) // return existing.(T) // 安全,因为同名的类型肯定相同 // } // log.Printf("缓存 %s 对象", name) // // 添加到order(保持顺序) // c.order = append(c.order, name) // // 存储到map // c.resources[name] = resource // return resource } // / Reg 直接注册已创建的对象 func Reg[T Resource](c *ContainerFactory, resource T) T { c.mu.Lock() defer c.mu.Unlock() name := resource.GetName() log.Printf("直接注册 %s 对象", name) // 如果已存在,返回已注册的对象(或报错) if existing, ok := c.resources[name]; ok { log.Printf("对象 %s 已经存在,跳过注册", name) // 可以选择返回已有的对象或什么都不做 return existing.(T) // 安全,因为同名的类型肯定相同 } log.Printf("缓存 %s 对象", name) // 添加到order(保持顺序) c.order = append(c.order, name) // 存储到map c.resources[name] = resource log.Printf("已注册 %s 对象", name) return resource } // 按添加顺序关闭(先进先出,最先添加的最先关闭) func (c *ContainerFactory) CloseAll() { c.mu.Lock() defer c.mu.Unlock() // 按添加顺序关闭 for _, name := range c.order { if res, ok := c.resources[name]; ok { res.Close() log.Printf("关闭 %s 对象", name) } } // 清空容器 c.resources = make(map[string]Resource) c.order = make([]string, 0) }