go语言实现ioc容器:基于类型的存储(1)

379 阅读1分钟

设计思路

  • 1.设计一个像Map的类型 key;reflect.Type value:reflect.Value

代码实现部分

  • OrderService.go
package services

import "fmt"

type OrderService struct {
	Version string
}

func NewOrderService() *OrderService{
	return &OrderService{Version: "0"}
}

func (this *OrderService) GetOrderInfo(uid int){
	fmt.Println("获取用户ID=",uid,"的订单信息")
}
  • UserService.go
package services

import "fmt"

type UserService struct {
	order *OrderService
}

func NewUserService(order *OrderService) *UserService{
	return &UserService{order: order}
}

func (this *UserService) GetUserInfo(uid int){
	fmt.Println("获取用户ID=",uid,"的详细信息")
}
func (this *UserService) GetOrderInfo(uid int){
	this.order.GetOrderInfo(uid)
}
  • BeanMapper.go
package Injector

import "reflect"

type BeanMapper map[reflect.Type]reflect.Value
func (this BeanMapper) add (bean interface{}){
	 t:=reflect.TypeOf(bean)
	 if t.Kind()!=reflect.Ptr{
	 	panic("require ptr object")
	 }
	 this[t] = reflect.ValueOf(bean)
}

func (this BeanMapper) get(bean interface{}) reflect.Value{
	t:=reflect.TypeOf(bean)
	if v,ok:=this[t];ok{
		return v
	}
	return reflect.Value{}

}
  • BeanFactory.go
package Injector

var BeanFactory *BeanFactoryImpl

func init(){
	BeanFactory = NewBeanFactory()
}


type BeanFactoryImpl struct {
	 beanMapper BeanMapper
}

func (this *BeanFactoryImpl) Set(vlist ...interface{}){
	if vlist == nil || len(vlist) == 0{
		return
	}
	for _,v:=range vlist{
		this.beanMapper.add(v)
	}
}
func (this *BeanFactoryImpl) Get(v interface{}) interface{}{
	if v==nil {
		return nil
	}
	get_v:=this.beanMapper.get(v)
	if get_v.IsValid(){
		return get_v.Interface()
	}
	return nil
}

func NewBeanFactory() *BeanFactoryImpl{
	return &BeanFactoryImpl{
		beanMapper: make(BeanMapper),
	}
}
  • main.go
package main

import (
	"fmt"
	"go.mod/Injector"
	"go.mod/services"
)

func main()  {

	Injector.BeanFactory.Set(services.NewOrderService())

	order:=Injector.BeanFactory.Get((*services.UserService)(nil))
	fmt.Println(order)
}