summer

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2021 License: Apache-2.0 Imports: 11 Imported by: 4

README

summer

The "summer" is a tiny dependency injection and autowiring package for GO language. It was deeply inspired by spring framework and try to implement some tiny portions of its functionality.

About "summer"

Being a beginner in writting something in Golang, I was searching for something similar to spring framework in Java's world ... and I ended up writing my own. So, the "summer" was born.

Go and Java are quite diffent in many ways, and I have no idea whether "Inversion of Control" or "Dependency Injection" is idiomatic Go code should be use or how, so ... mimic other language might be a worse idea.

Installation

To install summer, use go get:

go get github.com/linuzilla/summer
How to Use

Add tag "inject" on Fields (as following example) need a dependency injection. Put "*" as it's value which means it require a Type-based injection, or put a name, "kitty" for example, which means a Name-baed injection.

type Dog struct {
	Icat *ICat   `inject:"kitty"`
	Rabb *Rabbit `inject:"*"`
}

For a Interface pointer or a private field, a proper setter is required to make injection working properly. And the setter is always the first priority to be chosen to inject dependency. Simply put "Set" in front of the field's name as its setter.

func (d *Dog) SetIcat(icat interface{}) {
	if origional, ok := icat.(ICat); ok {
		d.Icat = &origional
	}
}

Like @PostConstruct in spring framework, this package provide a "Summerized" interface and a PostSummerConstruct() function should be implemented if your stuct needed to be called after dependency inject

func (d *Dog) PostSummerConstruct() {
	fmt.Println("Post Construct")
}

The main func look simething like this ...

package main

import (
	"github.com/linuzilla/summer"
)

func main() {
	applicationContext := summer.NewSummer();

	applicationContext.Add(new (sub.Dog), new (sub.Tiger))
	applicationContext.AddWithName("kitty", new (sub.Cat))

	done := applicationContext.Autowiring(func (err bool) {
		if err {
			fmt.Println("Failed to autowiring.")
		} else {
			fmt.Println("Autowired.")

			if result := applicationContext.GetByName("rabbit"); result != nil {
				rabbit := result.(*sub.Rabbit)
				rabbit.Jump()
			}
		}
	});

	err := <-done

	if ! err {
		var icat sub.ICat

		if result := applicationContext.Get(&icat); result != nil {
			icat = result.(sub.ICat)
			icat.Purr()
		}

		var dog *sub.Dog

		if result := applicationContext.Get(dog); result != nil {
			dog = result.(*sub.Dog)
			dog.DoSomething()
		}
	}
}

Documentation

Overview

Try to provide "dependency injection" mechanism on the Go world.

Index

Constants

View Source
const DefaultInjectionTag = `inject`
View Source
const DefaultPluginNamePrefix = `plugin#`
View Source
const (
	StatusOK errCode = 200
)

Variables

This section is empty.

Functions

func PrintStruct

func PrintStruct(something interface{})

func Stream added in v0.1.0

func Stream(dataSlice interface{}) *stream

func StreamOfList added in v0.1.0

func StreamOfList(aList *list.List) *stream

Types

type ApplicationContextManager added in v0.1.0

type ApplicationContextManager interface {
	// Add "beans" to, the "bean" should be a "pointer" or "interface", however, "pointer to interface" is not recommended.
	Add(beans ...interface{}) ApplicationContextManager

	// To avoid more the one candidate "beans", use name to distinguish between them.
	AddWithName(beanName string, bean interface{}) ApplicationContextManager

	// To perform dependency injection.
	Autowiring(callback func(err error)) chan error

	// a newer version of "Autowiring" function
	PerformAutoWiring(onError func(err error)) ApplicationContextManager

	// retrieve bean based on argument variable type, argument should be a "pinter to interface" or "pointer to structure".
	Get(intf interface{}) (interface{}, error)

	// retrieve bean by name
	GetByName(beanName string) (interface{}, error)

	// iterate over every beans which match the interface in the context
	ForEach(match interface{}, callback func(data interface{})) int

	// iterate over all wired beans
	Each(callback func(data interface{})) int

	// plugin can be loaded and put them in the context and perform dependency injection as well.
	// every plugin can only inject a variable using plugin's filename as variable name
	// LoadPlugins will try the find the exported variable using "FileNameToExportedVariable" function
	LoadPlugins(path string, callback func(beanName string, file string, module interface{}, err error)) error

	// If the default "exported variable name" converting function not suite for you,
	// provide a relevant one.
	SetExportedVariableNameFunc(function func(string) string)

	// To distinguish between plugins loaded by LoadPlugins, every plugin will added to application context
	// with a name associated with it.  The name, by default, will be the "variable name" prefixed by "plugin#",
	// However, you can choose the prefix you wanted calling "SetPluginsBeanNamePrefix" before "LoadPlugins"
	SetPluginBeanNamePrefix(prefix string)

	// By default, The setter name of a variable is follow Java's setter idea with the first letter 'S' capitalized.
	// However, there is no standard "setter" function in Go world
	SetSetterNameFunc(function func(string) string)

	// The field wanted to be inject require a tag, the default tag is 'inject'.
	// Change tag name if other name is desired
	SetTagName(tagName string)

	Debug(on bool)
}

func Initialize added in v0.1.0

func Initialize(callback func(ApplicationContextManager), onError func(error)) ApplicationContextManager

func New added in v0.1.0

type HavePostConstruct added in v0.1.0

type HavePostConstruct interface {
	PostSummerConstruct()
}

kind of like "@PostConstruct" in Spring framework

Directories

Path Synopsis
sub

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL