Jacket of google/wire: advanced DI approach wrapping google/wire for cloud.

Overview

Wire-Jacket: IoC Container of google/wire for cloud-native

GoDoc Github release Build Status Coverage Status Go Report Card

Jacket of google/wire: advanced DI approach wrapping google/wire for cloud.

A jacket is an outer sheath that groups wires and protects the core from external issues.

wire-jacket wraps google/wire and provides advanced DI(Dependency Injection) experience in cloud-native.

Installation

Install Wire-Jacket by running:

go get github.com/bang9211/wire-jacket

and ensuring that $GOPATH/bin is added to your $PATH.

Example

Wire-Jacket example of ossicones. In this example, ossicones is simple blockchain package. It consisted of only 3 components: Config, Database, Blockchain.

Define simple two Interface, Implement.

type Database interface {
    Connect() bool
    Close() error   //necessary for Wire Jacket
}

type MySQL struct {
    cfg config.Config
}

func NewMySQL(cfg config.Config) Database {
    return &MySQL{cfg : cfg}
}

func (m *MySQL) Connect() error {
    address := m.cfg.GetString("address", "localhost:3306")
    ...
    return nil
}

func (m *MySQL) Close() error {
    return nil
}
type Blockchain interface {
    Init() error
    Close() error   //necessary for Wire Jacket
}

type Ossicones struct {
    db *Database
}

func NewOssicones(db Database) Blockchain {
    return &Ossicones{db : db}
}

func (o *Ossicones) Init() error {
    err := o.db.Connect()
    ...
    return nil
}

func (o *Ossicones) Close() error {
    return nil
}

Suppose there is MongoDB that implements Database Interface like MySQL. And Wire-Jacket has ViperConfig by default.

Then, there are 3 Interfaces and 4 Implements.

  • Database Interface - MySQL, MongoDB Implement
  • Blockchain Interface - Ossicones Implement
  • (Default) Config Interface - ViperConfig Implement

Database depends on config.Config. Blockchain depends on Database.

The pair of interface and implement called module in Wire-Jacket.

Wire-Jacket helps to replace implement of interface easy way. And close modules gracefully. So the modules are closable, have to implment Close().

1. Create wire.go with injectors.

package wire

func InjectMySQL(cfg config.Config) (Database, error) {
	wire.Build(NewMySQL)
	return nil, nil
}

func InjectMongoDB(cfg config.Config) (Databsae, error) {
    wire.Build(NewMongoDB)
    return nil, nil
}

func InjectOssicones(db Database) (Blockchain, error) {
	wire.Build(NewOssicones)
	return nil, nil
}

// key will use in app.conf
var Injectors map[string]interface{} = {"mysql" : InjectMySQL}
var EagerInjectors map[string]interface{} = {"ossicones" : InjectOssicones}

2. Generate wire_gen.go using wire.

wire wire.go

wire is compile-time DI. It can verify validity of DI in compile-time.

3. Create app.conf(default way)

# Specify module to use.
modules=mysql ossicones

# And you can add any config to use.
db_host=localhost
db_port=3306

Choose modules to use mysql, ossicones.

Database binds to MySQL, Blockchain binds to Ossicones.

4. Create wirejacket, Set injectors, Call DoWire().

wj := wirejacket.New().
    SetInjectors(wire.Injectors).
    SetEagerInjectors(wire.EagerInjectors)

// inject eager injectors.
wj.DoWire()

Except for eager injectors, injectors are loaded lazy by default.

Or If you call wj.GetModule() to get the module you need, all the dependencies of the module will be injected automatically. you don't need to call DoWire() in this case. It is not necessary to call DoWire().

Assume that there is mongodb like mysql as the implementation of Database.

If you want to change implement of Database to mongodb, Just modify modules in config and restart app.

modules=mongodb ossicones

Features

  • google/wire based IoC Container
  • Environment-variable based setting for cloud
  • Lazy Loading, Eager Loading

Why Wire-Jacket needs?

google/wire works statically because it performs DI at compile-time. This approach is great for pre-debugging of DI.

It is difficult to debug problems that occur at runtime like dependency injection in a cloud environment. So It can be usefully used in a cloud environment.

Wire-Jacket wraps google/wire in order to use google/wire appropriately for the cloud environment.

1. IoC (Inversion of Control) Container

google/wire just provides injecting and binding features, do not have an IoC container. IoC Container makes it easy to version up and replace modules. You can also make a Plan B and keep it. For example, DB Skip mode that does not use DB or emergency processing mode that does not actually connect with other nodes can be applied by replacing module and restarting.

And it helps not to use singleton as a global variable. Automatically maintains and recycles one singleton object.

2. Binding based environment-variable for cloud.

The Twelve-Factors recommends use environment variables for configuration. Because it's good in container, cloud environments. However, it is not efficient to express all configs as environment variables.

So, we adopted viper, which integrates most config formats with environment variables in go. By using viper, you can use various config file formats without worrying about conversion to environment variables even if it is not in env format like json, yaml, toml, etc.

In Wire-Jacket, modules to use set in config file. For example, if you use the MySQL DB implementation in your app and want to replace the implementation with MongoDB, you don't need to change the code.

just change MySQL to MongoDB in config and restart the app.

3. Modulization, Loose-Coupling.

Wirejacket uses the simple approach of injecting implement into the interface. This approach simplifies and allows the team leader or designer to define the interface required for the project and effectively divide the work. the each implementation can be integrated easily and replaced as a plug-in using the config file.

Issues
Releases(v1.1.4)
  • v1.1.4(Oct 15, 2021)

    Minor Changes of viperconfig.

    ViperConfig changed to ViperJacket it reads value of string, string slice, string map string using os.expandEnv() It is processed so that it can operate properly even in unintended situations.

    Full Changelog: https://github.com/bang9211/wire-jacket/compare/v1.1.3...v1.1.4

    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Oct 13, 2021)

    Minor Changes of viperconfig.

    ViperConfig reads value of string, string map string using os.expandEnv()

    Full Changelog: https://github.com/bang9211/wire-jacket/compare/v1.1.2...v1.1.3

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Oct 9, 2021)

    Minor Changes of wirejacket, viperconfig.

    • ViperConfig works as singleton.

    Full Changelog: https://github.com/bang9211/wire-jacket/compare/v1.1.1...v1.1.2

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Oct 6, 2021)

    Added examples, Minor changes of readme, comments, wirejacket, test.

    Full Changelog: https://github.com/bang9211/wire-jacket/compare/v1.1.0...v1.1.1

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Oct 6, 2021)

    Changed Wire-Jacket default features.

    • Wire-Jacket uses app.conf by default.
    • Changed 'activating_modules' to 'modules' in config.
    • If serviceName exists, it use value of {serviceName}_modules in config.
    • If serviceName no exists, it use value of 'modules' in config Viper Test Bug Fixed.

    Full Changelog: https://github.com/bang9211/wire-jacket/compare/v1.0.0...v1.1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Sep 27, 2021)

Owner
Youngtak Han
Have a little fun.
Youngtak Han
golang auto wire code generator

Go-AutoWire helps you to generate wire files with easy annotate 中文文档 this project is base on wire but it did simplify the wire usage and make wire muc

null 19 Oct 15, 2021
Compile-time Dependency Injection for Go

Wire: Automated Initialization in Go Wire is a code generation tool that automates connecting components using dependency injection. Dependencies betw

Google 6.7k Oct 24, 2021
Go Dependency Injection Framework

Dingo Dependency injection for go Hello Dingo Dingo works very very similiar to Guice Basically one binds implementations/factories to interfaces, whi

Flamingo 110 Oct 14, 2021
Compile-time dependency injection for Go

Dihedral Dihedral is a compile-time injection framework for Go. Getting started > go get -u github.com/dimes/dihedral Create a type you want injected

null 76 Sep 4, 2020
Serverless Container Workflows

direktiv event-based serverless container workflows Check out our online demo: wf.direktiv.io What is Direktiv? Direktiv is a specification for a serv

vorteil.io pty ltd 113 Oct 23, 2021
🛠 A full-featured dependency injection container for go programming language.

DI Dependency injection for Go programming language. Tutorial | Examples | Advanced features Dependency injection is one form of the broader technique

Goava 106 Oct 19, 2021
digpro is a enhanced uber-go/dig

Introduction digpro is a enhanced uber-go/dig, inherit all feature of uber-go/dig and add the following features: Progressive

null 1 Oct 14, 2021
Generated dependency injection containers in go (golang)

Generation of dependency injection containers for go programs (golang). Dingo is a code generator. It generates dependency injection containers based

null 64 Oct 5, 2021