___ ___ ____ ____ _
|_ _| / _ \ / ___| / ___| ___ | | __ _ _ __ __ _
| | | | | | | | _____ | | _ / _ \ | | / _` | | '_ \ / _` |
| | | |_| | | |___ |_____| | |_| | | (_) | | | | (_| | | | | | | (_| |
|___| \___/ \____| \____| \___/ |_| \__,_| |_| |_| \__, |
|___/
IOC-Golang is a powerful golang dependency injection framework that provides a complete implementation of IoC containers. Its capabilities are as follows:
-
Supports dependency injection of any structure and interface.
-
Object life cycle management mechanism.
Can take over object creation, parameter injection, factory methods. Customizable object parameter source.
-
Based on the idea of AOP, it provides runtime monitoring and debugging capabilities for object methods taken over by the framework.
-
Automatic struct descriptor codes generation capability
We provide a code generation tool, and developers can annotate the structure through annotations, so as to easily generate structure registration code.
-
Support the extension of struct to be injected, the extension of autowire model, and the extension of the debug AOP layer.
-
Complete prefabricated components
Provides prefabricated objects covering mainstream middleware sdk for injection.
-
autowire: Provides two basic injection models: singleton model and multi-instance model
-
config: Configuration loading module, responsible for parsing user yaml configuration files
-
debug: Debug module: Provide debugging API, provide debugging injection layer implementation
-
extension: Component extension directory: Provides preset implementation structures based on various injection models:
-
autowire: autoload model extensions
-
grpc: grpc client model definition
-
config: configure the model definition
-
-
config: configuration injection model extension structure
- string,int,map,slice
-
normal: multi-instance model extension structure
-
redis
-
mysql
-
rocketmq
-
nacos
-
-
singleton: singleton model extension structure
- http-server
-
-
example: example repository
-
iocli: code generation/program debugging tool
go install github.com/alibaba/ioc-golang/iocli@latest
We will develop a project with the following topology, This tutorial can show:
- Registry codes generation
- Interface injection
- Struct pointer injection
- Get object by API
- Debug capability, list interface, implementations and methods; watch real-time param and return value.
All the code the user needs to write: main.go
package main
import (
"fmt"
"time"
"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:"main.ServiceImpl1"` // inject Service 's ServiceImpl1 implementation
ServiceImpl2 Service `singleton:"main.ServiceImpl2"` // inject Service 's ServiceImpl2 implementation
ServiceStruct *ServiceStruct `singleton:"main.ServiceStruct"` // inject ServiceStruct struct pointer
}
func (a*App) Run(){
for {
time.Sleep(time.Second*3)
a.ServiceImpl1.Hello()
a.ServiceImpl2.Hello()
fmt.Println(a.ServiceStruct.GetString("laurence"))
}
}
type Service interface{
Hello()
}
// +ioc:autowire=true
// +ioc:autowire:type=singleton
type ServiceImpl1 struct {
}
func (s *ServiceImpl1) Hello(){
fmt.Println("This is ServiceImpl1, hello world")
}
// +ioc:autowire=true
// +ioc:autowire:type=singleton
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) GetString(name string)string{
return fmt.Sprintf("Hello %s", name)
}
func main(){
// start
if err := ioc.Load(); err != nil{
panic(err)
}
// We can get instance by this id: "${pkgName}.${structName}"
appInterface, err := singleton.GetImpl("main.App")
if err != nil{
panic(err)
}
app := appInterface.(*App)
app.Run()
}
After writing, you can exec the following cli command to init go mod and generate codes. (mac may require sudo due to permissions during code generation)
% go mod init ioc-golang-demo
% go mod tidy
% sudo iocli gen
It will be generated in the current directory: zz_generated.ioc.go, developers do not need to care about this file, this file contains the description information of all interfaces,
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// Code generated by iocli
package main
import (
autowire "github.com/alibaba/ioc-golang/autowire"
"github.com/alibaba/ioc-golang/autowire/singleton"
)
func init() {
singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
Factory: func() interface{} {
return &App{}
},
})
singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
Factory: func() interface{} {
return &ServiceImpl1{}
},
})
singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
Factory: func() interface{} {
return &ServiceImpl2{}
},
})
singleton.RegisterStructDescriptor(&autowire.StructDescriptor{
Factory: func() interface{} {
return &ServiceStruct{}
},
})
}
See the file tree:
% tree
.
├── go.mod
├── go.sum
├── main.go
└── zz_generated.ioc.go
Run with general mode
go run .
Console printout:
___ ___ ____ ____ _
|_ _| / _ \ / ___| / ___| ___ | | __ _ _ __ __ _
| | | | | | | | _____ | | _ / _ \ | | / _` | | '_ \ / _` |
| | | |_| | | |___ |_____| | |_| | | (_) | | | | (_| | | | | | | (_| |
|___| \___/ \____| \____| \___/ |_| \__,_| |_| |_| \__, |
|___/
Welcome to use ioc-golang!
[Boot] Start to load ioc-golang config
[Config] Load default config file from ../conf/ioc_golang.yaml
[Config] Load ioc-golang config file failed. open alibaba/IOC-Golang/example/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 main.App
[Autowire Struct Descriptor] Found type singleton registered SD main.ServiceImpl1
[Autowire Struct Descriptor] Found type singleton registered SD main.ServiceImpl2
[Autowire Struct Descriptor] Found type singleton registered SD main.ServiceStruct
This is ServiceImpl1, hello world
This is ServiceImpl2, hello world
Hello laurence
...
It shows that the injection is successful and the program runs normally.
Run with debug mode
GOARCH=amd64 go run -gcflags="-N -l" -tags iocdebug .
Following logs can be found in console output:
[Debug] Debug server listening at :1999
List all interface, implementations and methods
% iocli list
main.App
[Run]
main.ServiceImpl1
[Hello]
main.ServiceImpl2
[Hello]
main.ServiceStruct
[GetString]
Watch real-time param and return value. We take 'GetString' method as an example. The method would be called every 3s .
% iocli watch main.ServiceStruct GetString
========== On Call ==========
main.ServiceStruct.GetString()
Param 1: (string) (len=8) "laurence"
========== On Response ==========
main.ServiceStruct.GetString()
Response 1: (string) (len=14) "Hello laurence"
...
// +ioc:autowire=true
The code generation tool recognizes objects marked with the +ioc:autowire=true annotation
// +ioc:autowire:type=singleton
The marker autowire model is the singleton, as well as the normal multi-instance model, the config configuration model, the grpc client model and other extensions.
More code generation annotations can be viewed at ioc-golang-cli.
You can go to ioc-golang-example for more examples and advanced usage.
IOC-Golang developed by Alibaba and licensed under the Apache License (Version 2.0). See the NOTICE file for more information.