Documentation ¶
Overview ¶
Package wirejacket is a IoC Container of google/wire for cloud-native
Example ¶
Default use case to use New(). Wire-Jacket defaultly uses 'app.conf' for setting modules to activate. Or you can use the flag '--config {file_name}'.
package main import ( "fmt" "log" wirejacket "github.com/bang9211/wire-jacket" ) // ============================================== // Database Interface - MockupDB Implement example // ============================================== type Database interface { Connect() error Close() error } type MockupDB struct{} func NewMockupDB() Database { return &MockupDB{} } func (mdb *MockupDB) Connect() error { return nil } func (mdb *MockupDB) Close() error { return nil } // ========================================================= // Blockchain Interface - MockupBlockchain Implement example // ========================================================= type Block interface { GetData() string } type MockupBlock struct { data string } func (mb *MockupBlock) GetData() string { return mb.data } type Blockchain interface { Init() error AddBlock(data string) error GetBlocks() []Block Close() error } var genesisBlockData = "Genesis Block Data" type MockupBlockchain struct { db Database blocks []Block } func NewMockupBlockchain(db Database) Blockchain { return &MockupBlockchain{db: db, blocks: []Block{}} } func (mbc *MockupBlockchain) Init() error { mbc.db.Connect() mbc.AddBlock(genesisBlockData) return nil } func (mbc *MockupBlockchain) AddBlock(data string) error { mbc.blocks = append(mbc.blocks, &MockupBlock{data: data}) return nil } func (mbc *MockupBlockchain) GetBlocks() []Block { return mbc.blocks } func (mbc *MockupBlockchain) Close() error { return nil } // InjectMockupDB injects dependencies and inits of Database. func InjectMockupDB() (Database, error) { database := NewMockupDB() return database, nil } // InjectMockupBlockchain injects dependencies and inits of Blockchain. func InjectMockupBlockchain(db Database) (Blockchain, error) { blockchain := NewMockupBlockchain(db) return blockchain, nil } var Injectors = map[string]interface{}{ "mockup_database": InjectMockupDB, } var EagerInjectors = map[string]interface{}{ "mockup_blockchain": InjectMockupBlockchain, } func main() { // Create wirejacket and set injectors. wj := wirejacket.New(). SetEagerInjectors(EagerInjectors). SetInjectors(Injectors) defer wj.Close() // Inject eager injectors. if err := wj.DoWire(); err != nil { // Error occured in this example, because there is no app.conf and modules. log.Print(err) } // You can set modules using SetActivatingModules() directly without app.conf. wj.SetActivatingModules([]string{"mockup_blockchain", "mockup_database"}) // Get module and use. blockchain := wj.GetModule("mockup_blockchain").(Blockchain) blockchain.AddBlock("test") fmt.Println(blockchain.GetBlocks()) }
Output:
Example (Second) ¶
Second use case to use NewWithServiceName().
package main import ( "fmt" wirejacket "github.com/bang9211/wire-jacket" ) // ============================================== // Database Interface - MockupDB Implement example // ============================================== type Database interface { Connect() error Close() error } type MockupDB struct{} func NewMockupDB() Database { return &MockupDB{} } func (mdb *MockupDB) Connect() error { return nil } func (mdb *MockupDB) Close() error { return nil } // ========================================================= // Blockchain Interface - MockupBlockchain Implement example // ========================================================= type Block interface { GetData() string } type MockupBlock struct { data string } func (mb *MockupBlock) GetData() string { return mb.data } type Blockchain interface { Init() error AddBlock(data string) error GetBlocks() []Block Close() error } var genesisBlockData = "Genesis Block Data" type MockupBlockchain struct { db Database blocks []Block } func NewMockupBlockchain(db Database) Blockchain { return &MockupBlockchain{db: db, blocks: []Block{}} } func (mbc *MockupBlockchain) Init() error { mbc.db.Connect() mbc.AddBlock(genesisBlockData) return nil } func (mbc *MockupBlockchain) AddBlock(data string) error { mbc.blocks = append(mbc.blocks, &MockupBlock{data: data}) return nil } func (mbc *MockupBlockchain) GetBlocks() []Block { return mbc.blocks } func (mbc *MockupBlockchain) Close() error { return nil } // InjectMockupDB injects dependencies and inits of Database. func InjectMockupDB() (Database, error) { database := NewMockupDB() return database, nil } // InjectMockupBlockchain injects dependencies and inits of Blockchain. func InjectMockupBlockchain(db Database) (Blockchain, error) { blockchain := NewMockupBlockchain(db) return blockchain, nil } func main() { // Create wirejacket with serviceName. wj := wirejacket.NewWithServiceName("example_service") defer wj.Close() // You can also add injector directly, instead of SetInjectors(). wj.AddInjector("mockup_database", InjectMockupDB) wj.AddEagerInjector("mockup_blockchain", InjectMockupBlockchain) // Check value of modules in app.conf. // Or You can set modules using SetActivatingModules() directly. wj.SetActivatingModules([]string{"mockup_blockchain", "mockup_database"}) // You can also get module without DoWire(). // the dependencies of the module are injected automatically. blockchain := wj.GetModule("mockup_blockchain").(Blockchain) blockchain.AddBlock("test") fmt.Println(blockchain.GetBlocks()) }
Output:
Index ¶
- Constants
- func GetConfig() viperjacket.Config
- type Module
- type WireJacket
- func (wj *WireJacket) AddEagerInjector(moduleName string, injector interface{})
- func (wj *WireJacket) AddInjector(moduleName string, injector interface{})
- func (wj *WireJacket) Close() error
- func (wj *WireJacket) DoWire() error
- func (wj *WireJacket) GetModule(moduleName string) interface{}
- func (wj *WireJacket) GetModuleByType(interfaceType interface{}) interface{}
- func (wj *WireJacket) SetActivatingModules(moduleNames []string)
- func (wj *WireJacket) SetEagerInjectors(injectors map[string]interface{}) *WireJacket
- func (wj *WireJacket) SetInjectors(injectors map[string]interface{}) *WireJacket
Examples ¶
Constants ¶
const DefaultConfigName = "viperjacket"
const DefaultModulesKey = "modules"
Variables ¶
This section is empty.
Functions ¶
func GetConfig ¶ added in v1.1.2
func GetConfig() viperjacket.Config
GetConfig returns config object.
Types ¶
type Module ¶
type Module interface { // Close closes module gracefully. Close() error }
All the module should have Close().
type WireJacket ¶
type WireJacket struct {
// contains filtered or unexported fields
}
WireJacket structure. the jacket of the wires(injectors).
func New ¶
func New() *WireJacket
New creates empty WireJacket. If you want to use more than one WireJacket on the same system, Use NewWithServiceName with unique serviceName instead of New(). By default, WireJacket reads list of module name to activate in 'modules' value of viperjacket.
But Wire-Jacket considered The Twelve Factors. Config can be overrided by envrionment variable.(see viperjacket.go) So, when using more than one WireJacket on the same system, each WireJacket should have a unique service name to avoid conflicting value of 'modules'.
If serviceName no exists, WireJacket reads value of 'modules'. By default, WireJacket reads app.conf. Or you can specify file with '--config' flag.(see viperjacket.go)
modules example in app.conf without serviceName
ossicones_modules=mysql ossiconesblockchain defaultexplorerserver defaultrestapiserver
SetActivatingModules can specify activating modules without viperjacket. But this way is needed re-compile for changing module. The list of activating modules is used as key of injectors to call.
func NewWithServiceName ¶ added in v1.1.0
func NewWithServiceName(serviceName string) *WireJacket
NewWithServiceName creates empty WireJacket. Make sure the serviceName is unique in same system. By default, WireJacket reads list of module name to activate in 'modules' value of viperjacket.
But Wire-Jacket considered The Twelve Factors. Config can be overrided by envrionment variable.(see viperjacket.go) So, when using more than one WireJacket on the same system, each WireJacket should have a unique service name to avoid conflicting value of 'modules'.
If serviceName exists, WireJacket reads value of '{serviceName}_modules' in viperjacket. the spaces of serviceName will be changed to '_'. serviceName will be used in config, we don't recommend it to contain space.
By default, WireJacket reads app.conf. Or you can specify file with '--config' flag.(see viperjacket.go)
modules example in app.conf with serviceName(ossicones)
ossicones_modules=mysql ossiconesblockchain defaultexplorerserver defaultrestapiserver
SetActivatingModules can specify activating modules without viperjacket. But this way is needed re-compile for changing module. The list of activating modules is used as key of injectors to call.
func (*WireJacket) AddEagerInjector ¶
func (wj *WireJacket) AddEagerInjector(moduleName string, injector interface{})
AddInjector adds injector function to the eager injection list.
func (*WireJacket) AddInjector ¶
func (wj *WireJacket) AddInjector(moduleName string, injector interface{})
AddInjector adds injector function to the lazy injection list.
func (*WireJacket) Close ¶
func (wj *WireJacket) Close() error
Close closes all the modules gracefully
func (*WireJacket) DoWire ¶
func (wj *WireJacket) DoWire() error
DoWire does wiring of wires(injectors). It calls eagerInjectors as finding(if no exists, loading) and injecting dependencies.
func (*WireJacket) GetModule ¶
func (wj *WireJacket) GetModule(moduleName string) interface{}
GetModule finds module using moduleName and returns module if exists. If no exists, it tries to create module using injector and returns.
func (*WireJacket) GetModuleByType ¶
func (wj *WireJacket) GetModuleByType(interfaceType interface{}) interface{}
GetModuleByType finds module using interfaceType(pointer of interface) and returns module if exists.
Example (process_name=ossicones) :
config := wj.GetModuleByType((*viperjacket.Config)(nil))
If no exists, it tries to create module using injector and returns. This may return undesirable results if there are other implementations that may use the same interface. Use only if you are sure that there are no overlapping interfaces.
func (*WireJacket) SetActivatingModules ¶
func (wj *WireJacket) SetActivatingModules(moduleNames []string)
SetActivatingModules sets list of module's name. module's name is used as key of injector maps. It overwrites list of modules to activate.
func (*WireJacket) SetEagerInjectors ¶
func (wj *WireJacket) SetEagerInjectors(injectors map[string]interface{}) *WireJacket
SetEagerInjectors sets injectors to inject eagerly. WireJacket maps module_name to injector as a key-value pairs. WireJacket tries to find module_name. if serviceName no exists, value of 'modules' in viperjacket. if serviceName exists, value of '{serviceName}_modules' in viperjacket.
modules example of app.conf (serviceName=ossicones) :
ossicones_modules=mysql ossiconesblockchain defaultexplorerserver defaultrestapiserver
definition in wire.go
func InjectMySQL(config viperjacket.Config) (database.Database, error) { ... } func InjectOssiconesBlockchain(config viperjacket.Config, database.Database) (blockchain.Blockchain, error) { ... } func InjectDefaultExplorerServer(config viperjacket.Config, blockchain blockchain.Blockchain) (explorerserver.ExplorerServer, error) { ...} func InjectDefaultRESTAPIServer(config viperjacket.Config, blockchain blockchain.Blockchain) (restapiserver.RESTAPIServer, error) { ...}
injectors can be like this.
var injectors = map[string]interface{}{ "mysql": InjectMySQL, "ossiconesblockchain": InjectOssiconesBlockchain, }
eagerInjectors can be like this.
var eagerInjectors = map[string]interface{}{ "defaultexplorerserver": InjectDefaultExplorerServer, "defaultrestapiserver": InjectDefaultRESTAPIServer, }
injectors will be injected eagerly.
func (*WireJacket) SetInjectors ¶
func (wj *WireJacket) SetInjectors(injectors map[string]interface{}) *WireJacket
SetInjectors sets injectors to inject lazily. WireJacket maps module_name to injector as a key-value pairs. WireJacket tries to find module_name. if serviceName no exists, value of 'modules' in viperjacket. if serviceName exists, value of '{serviceName}_modules' in viperjacket.
modules example of app.conf (serviceName=ossicones) :
ossicones_modules=mysql ossiconesblockchain defaultexplorerserver defaultrestapiserver
definition in wire.go
func InjectMySQL(config viperjacket.Config) (database.Database, error) { ... } func InjectOssiconesBlockchain(config viperjacket.Config, database.Database) (blockchain.Blockchain, error) { ... } func InjectDefaultExplorerServer(config viperjacket.Config, blockchain blockchain.Blockchain) (explorerserver.ExplorerServer, error) { ...} func InjectDefaultRESTAPIServer(config viperjacket.Config, blockchain blockchain.Blockchain) (restapiserver.RESTAPIServer, error) { ...}
injectors can be like this.
var injectors = map[string]interface{}{ "mysql": InjectMySQL, "ossiconesblockchain": InjectOssiconesBlockchain, }
eagerInjectors can be like this.
var eagerInjectors = map[string]interface{}{ "defaultexplorerserver": InjectDefaultExplorerServer, "defaultrestapiserver": InjectDefaultRESTAPIServer, }
injectors will be injected lazily.