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