实现依赖注入demo

使用 ioc-golang 实现依赖注入demo

教程

我们将开发一个具有以下拓扑的工程,在本例子中,可以展示代码生成、接口注入、对象指针注入、API 获取对象能力。 ioc-golang-quickstart-structure

用户所需编写的全部代码:main.go

package main

import (
	"fmt"
	"github.com/alibaba/ioc-golang"
	"github.com/alibaba/ioc-golang/autowire/singleton"
)

// +ioc:autowire=true
// +ioc:autowire:type=singleton

type App struct {
	ServiceImpl1 Service `singleton:"ServiceImpl1"` // 要求注入Service 的 ServiceImpl1 实现
	ServiceImpl2 Service `singleton:"ServiceImpl2"` // 要求注入Service 的 ServiceImpl2 实现
	ServiceStruct *ServiceStruct `singleton:"ServiceStruct"` // 要求注入 ServiceStruct 指针
}

func (a*App) Run(){
	a.ServiceImpl1.Hello()
	a.ServiceImpl2.Hello()
	a.ServiceStruct.Hello()
}


type Service interface{
	Hello()
}

// +ioc:autowire=true
// +ioc:autowire:type=singleton
// +ioc:autowire:interface=Service

type ServiceImpl1 struct {

}

func (s *ServiceImpl1) Hello(){
	fmt.Println("This is ServiceImpl1, hello world")
}

// +ioc:autowire=true
// +ioc:autowire:type=singleton
// +ioc:autowire:interface=Service

type ServiceImpl2 struct {

}

func (s *ServiceImpl2) Hello(){
	fmt.Println("This is ServiceImpl2, hello world")
}

// +ioc:autowire=true
// +ioc:autowire:type=singleton

type ServiceStruct struct {

}

func (s *ServiceStruct) Hello(){
	fmt.Println("This is ServiceStruct, hello world")
}

func main(){
	// 框架启动
	if err := ioc.Load(); err != nil{
		panic(err)
	}

	// App-App 即结构ID: '$(接口名)-$(结构名)', 对于结构指针,接口名默认为结构名
	// 可通过这一 ID 获取实例
	appInterface, err := singleton.GetImpl("App-App")
	if err != nil{
		panic(err)
	}
	app := appInterface.(*App)
	app.Run()
}

编写完毕后,当前目录命令行执行(mac 环境可能因为权限原因需要sudo):

sudo ioc-go-cli gen

会在当前目录生成:zz_generated.ioc.go,开发者无需关心这一文件,该文件包含了所有接口的描述信息,

//go:build !ignore_autogenerated
// +build !ignore_autogenerated

// Code generated by ioc-go-cli

package main

import (
	"github.com/alibaba/ioc-golang/autowire"
	"github.com/alibaba/ioc-golang/autowire/singleton"
)

func init() {
	singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
		Interface: &App{},
		Factory: func() interface{} {
			return &App{}
		},
	})
	singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
		Interface: new(Service),
		Factory: func() interface{} {
			return &ServiceImpl1{}
		},
	})
	singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
		Interface: new(Service),
		Factory: func() interface{} {
			return &ServiceImpl2{}
		},
	})
	singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
		Interface: &ServiceStruct{},
		Factory: func() interface{} {
			return &ServiceStruct{}
		},
	})
}

初始化 go mod ,执行

% go mod init ioc-golang-demo
% go mod tidy
% tree
.
├── go.mod
├── go.sum
├── main.go
└── zz_generated.ioc.go

执行程序:

go run .

控制台打印输出:

  ___    ___     ____            ____           _                         
 |_ _|  / _ \   / ___|          / ___|   ___   | |   __ _   _ __     __ _ 
  | |  | | | | | |      _____  | |  _   / _ \  | |  / _` | | '_ \   / _` |
  | |  | |_| | | |___  |_____| | |_| | | (_) | | | | (_| | | | | | | (_| |
 |___|  \___/   \____|          \____|  \___/  |_|  \__,_| |_| |_|  \__, |
                                                                    |___/ 
Welcome to use ioc-golang!
[Boot] Start to load ioc-golang config
[Config] Load config file from ../conf/ioc_golang.yaml
Load ioc_golang config file failed. open ../conf/ioc_golang.yaml: no such file or directory
 The load procedure is continue
[Boot] Start to load debug
[Debug] Debug mod is not enabled
[Boot] Start to load autowire
[Autowire Type] Found registered autowire type singleton
[Autowire Struct Descriptor] Found type singleton registered SD App-App
[Autowire Struct Descriptor] Found type singleton registered SD Service-ServiceImpl1
[Autowire Struct Descriptor] Found type singleton registered SD Service-ServiceImpl2
[Autowire Struct Descriptor] Found type singleton registered SD ServiceStruct-ServiceStruct
This is ServiceImpl1, hello world
This is ServiceImpl2, hello world
This is ServiceStruct, hello world

可看到,注入成功,程序正常运行。

更多

您可以参阅 示例 查阅更多例子和框架高级用法


Last modified May 19, 2022: Fix: update docs (75dddd7)