goft-gin

在B站看到以Goft-gin(https://github.com/shenyisyn/goft-gin)为基础的DDD视频,那么今天就和这个Goft-gin来简单交流一下。整体上Goft-gin,在Gin框架为基础,增加了一些依赖注入,表达式等。细节就不说了,以下列出了我看到的一些东西

  1. IoC and DI

    IoC(Inversion of Conctrol) ,DI(Dependency Injection),简单来说IOC是将对象的创建过程由主动创建交给容器控制,而DI是IoC的一种实现方式,可参考(https://stackoverflow.com/questions/6550700/inversion-of-control-vs-dependency-injection

    Goft-gin如何来做这件事

// 定义工厂类型及其方法
func NewMyConfig() *MyConfig {
  return &MyConfig{}
}

func (this *MyConfig) Test() *Services.TestService {  // 工厂类型的方法
  return Services.NewTestService("mytest")
}

// 全局Map定义
type BeanMapper map[reflect.Type]reflect.Value

type BeanFactoryImpl struct {
  beanMapper BeanMapper
  ExprMap    map[string]interface{}
}

// 通过反射来,遍历工厂类的所有方法,结果存入全局Map
func (this *BeanFactoryImpl) Config(cfgs ...interface{}) {
  for _, cfg := range cfgs {
    t := reflect.TypeOf(cfg)
    if t.Kind() != reflect.Ptr {
      panic("required ptr object") //必须是指针对象
    }
    if t.Elem().Kind() != reflect.Struct {
      continue
    }
    this.Set(cfg)                       
    this.ExprMap[t.Elem().Name()] = cfg 
    this.Apply(cfg)                     
    v := reflect.ValueOf(cfg)
    for i := 0; i < t.NumMethod(); i++ {
      method := v.Method(i)
      callRet := method.Call(nil)   // 工厂类型的方法被调用

      if callRet != nil && len(callRet) == 1 {
        this.Set(callRet[0].Interface())  // 调用结果存入全局Map
      }
    }
  }
  }
  
// 处理依赖注入
func (this *BeanFactoryImpl) Apply(bean interface{}) {
  if bean == nil {
    return
  }
  v := reflect.ValueOf(bean)
  if v.Kind() == reflect.Ptr {
    v = v.Elem()
  }
  if v.Kind() != reflect.Struct {
    return
  }
  for i := 0; i < v.NumField(); i++ {
    field := v.Type().Field(i)
        if get_v := this.Get(field.Type); get_v != nil {
          v.Field(i).Set(reflect.ValueOf(get_v))
          this.Apply(get_v)
        }
      }
    }
  }
}

  1. 有意思的Go追踪错误的方式

    使用了Panic+Recover的方式,结合Gin中间件来使用,错误时通过panic来返回堆栈调用信息

    一般Go中,为了打印error的调用信息,会使用erros.wrap来层层封装调用信息,从而在发生错误时代替堆栈调用信息打印

    后续试试

  2. 链式调用模式:返回自身,代码清晰

goft.Ignite(cros(), errorFunc()).
    Config(Configuration.NewMyConfig()).
    Attach(fairing.NewGlobalFairing()).
    Mount("", classes.NewIndexClass()). //控制器,挂载到v1
    Config(Configuration.NewRouterConfig()).
    Launch()
posted @ 2023-02-27 07:23  cclever  阅读(294)  评论(0)    收藏  举报