feat: 新增 modular 包,用于实现模块化项目
This commit is contained in:
parent
6b24b7c576
commit
c95b206592
|
@ -0,0 +1,5 @@
|
||||||
|
package expose
|
||||||
|
|
||||||
|
type Attack interface {
|
||||||
|
Name() string
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package expose
|
||||||
|
|
||||||
|
type Login interface {
|
||||||
|
Name() string
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package attack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/modular/example/internal/service/expose"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Login expose.Login
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Service) OnInit() {
|
||||||
|
a.name = "attack"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Service) OnPreload() {
|
||||||
|
fmt.Println(a.name, "call", a.Login.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Service) OnMount() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Service) Name() string {
|
||||||
|
return a.name
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/modular/example/internal/service/expose"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Attack expose.Attack
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Service) OnInit() {
|
||||||
|
l.name = "login"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Service) OnPreload() {
|
||||||
|
fmt.Println(l.name, "call", l.Attack.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Service) OnMount() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Service) Name() string {
|
||||||
|
return l.name
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/modular"
|
||||||
|
"github.com/kercylan98/minotaur/modular/example/internal/service/services/attack"
|
||||||
|
"github.com/kercylan98/minotaur/modular/example/internal/service/services/login"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
modular.RegisterServices(
|
||||||
|
new(attack.Service),
|
||||||
|
new(login.Service),
|
||||||
|
)
|
||||||
|
modular.Run()
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package modular
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/utils/log"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
var application *modular
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
application = &modular{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type modular struct {
|
||||||
|
registerServices []Service
|
||||||
|
services []*service
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterServices 注册服务
|
||||||
|
func (m *modular) RegisterServices(s ...Service) {
|
||||||
|
application.registerServices = append(application.registerServices, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run 运行模块化应用程序
|
||||||
|
func Run() {
|
||||||
|
m := application
|
||||||
|
var names = make(map[string]bool)
|
||||||
|
var tvm = make(map[reflect.Type]reflect.Value)
|
||||||
|
for i := 0; i < len(m.registerServices); i++ {
|
||||||
|
s := newService(m.registerServices[i])
|
||||||
|
if names[s.name] {
|
||||||
|
panic(fmt.Errorf("service %s is already registered", s.name))
|
||||||
|
}
|
||||||
|
names[s.name] = true
|
||||||
|
tvm[s.vof.Type()] = s.vof
|
||||||
|
m.services = append(m.services, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnInit
|
||||||
|
for i := 0; i < len(m.services); i++ {
|
||||||
|
s := m.services[i]
|
||||||
|
s.instance.OnInit()
|
||||||
|
log.Info(fmt.Sprintf("service %s initialized", s.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnPreload
|
||||||
|
for i := 0; i < len(m.services); i++ {
|
||||||
|
s := m.services[i]
|
||||||
|
for f := 0; f < s.vof.Elem().NumField(); f++ {
|
||||||
|
field := s.vof.Elem().Field(f)
|
||||||
|
for _, v := range tvm {
|
||||||
|
if v.Type().AssignableTo(field.Type()) {
|
||||||
|
field.Set(v)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.instance.OnPreload()
|
||||||
|
log.Info(fmt.Sprintf("service %s preloaded", s.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnMount
|
||||||
|
for i := 0; i < len(m.services); i++ {
|
||||||
|
s := m.services[i]
|
||||||
|
s.instance.OnMount()
|
||||||
|
log.Info(fmt.Sprintf("service %s mounted", s.name))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package modular
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// Service 模块化服务接口,所有的服务均需要实现该接口,在服务的生命周期内发生任何错误均应通过 panic 阻止服务继续运行
|
||||||
|
// - 生命周期示例: OnInit -> OnPreload -> OnMount
|
||||||
|
type Service interface {
|
||||||
|
// OnInit 服务初始化阶段,该阶段不应该依赖其他任何服务
|
||||||
|
OnInit()
|
||||||
|
|
||||||
|
// OnPreload 预加载阶段,在进入该阶段时,所有服务已经初始化完成,可在该阶段注入其他服务的依赖
|
||||||
|
OnPreload()
|
||||||
|
|
||||||
|
// OnMount 挂载阶段,该阶段所有服务本身及依赖的服务都已经初始化完成,可在该阶段进行服务功能的定义
|
||||||
|
OnMount()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterServices 注册服务
|
||||||
|
func RegisterServices(s ...Service) {
|
||||||
|
application.RegisterServices(s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newService(instance Service) *service {
|
||||||
|
vof := reflect.ValueOf(instance)
|
||||||
|
return &service{
|
||||||
|
name: vof.Type().String(),
|
||||||
|
instance: instance,
|
||||||
|
vof: vof,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
name string
|
||||||
|
instance Service
|
||||||
|
vof reflect.Value
|
||||||
|
}
|
Loading…
Reference in New Issue