elliotchance / dingo Goto Github PK
View Code? Open in Web Editor NEW๐บ Easy, fast and type-safe dependency injection for Go.
License: MIT License
๐บ Easy, fast and type-safe dependency injection for Go.
License: MIT License
If referencing a service that doesn't exist like @{S3Client}
it will panic with a nil pointer instead of providing a useful message.
Right now services can be replaced by assigning to the instance variable (and also accessed) this is problematic for mixing scopes service may already be initialized, so we need to raise an error if one of its dependencies is trying to be replaced.
I have 4 services called Dep1, Dep2, Dep3 & Dep4 where Dep4 has Dep1, Dep2 & Dep3 as dependencies
services:
Dep1:
interface: app.Dep1
scope: prototype
returns: app.NewDefaultDep1()
Dep2:
interface: app.Dep2
scope: prototype
returns: app.NewDefaultDep2()
Dep3:
interface: app.Dep3
scope: prototype
returns: app.NewDefaultDep3()
Dep4:
interface: app.Dep4
scope: prototype
returns: app.NewDefaultDep4(@{Dep1}, @{Dep2}, @{Dep3})
Here is the first generated dingo.go (the order of parameters in Dep4's function in NewContainer() is different from the order in other places)
// Code generated by dingo; DO NOT EDIT
package main
import app "app"
type Container struct {
Dep1 func() app.Dep1
Dep2 func() app.Dep2
Dep3 func() app.Dep3
Dep4 func(Dep1 app.Dep1, Dep2 app.Dep2, Dep3 app.Dep3) app.Dep4
}
var DefaultContainer = NewContainer()
func NewContainer() *Container {
return &Container{Dep1: func() app.Dep1 {
service := app.NewDefaultDep1()
return service
}, Dep2: func() app.Dep2 {
service := app.NewDefaultDep2()
return service
}, Dep3: func() app.Dep3 {
service := app.NewDefaultDep3()
return service
}, Dep4: func(Dep3 app.Dep3, Dep1 app.Dep1, Dep2 app.Dep2) app.Dep4 {
service := app.NewDefaultDep4(Dep1, Dep2, Dep3)
return service
}}
}
func (container *Container) GetDep1() app.Dep1 {
return container.Dep1()
}
func (container *Container) GetDep2() app.Dep2 {
return container.Dep2()
}
func (container *Container) GetDep3() app.Dep3 {
return container.Dep3()
}
func (container *Container) GetDep4() app.Dep4 {
return container.Dep4(container.GetDep1(), container.GetDep2(), container.GetDep3())
}
Here is the second generated dingo.go (the order is the same in all places)
// Code generated by dingo; DO NOT EDIT
package main
import app "app"
type Container struct {
Dep1 func() app.Dep1
Dep2 func() app.Dep2
Dep3 func() app.Dep3
Dep4 func(Dep1 app.Dep1, Dep2 app.Dep2, Dep3 app.Dep3) app.Dep4
}
var DefaultContainer = NewContainer()
func NewContainer() *Container {
return &Container{Dep1: func() app.Dep1 {
service := app.NewDefaultDep1()
return service
}, Dep2: func() app.Dep2 {
service := app.NewDefaultDep2()
return service
}, Dep3: func() app.Dep3 {
service := app.NewDefaultDep3()
return service
}, Dep4: func(Dep1 app.Dep1, Dep2 app.Dep2, Dep3 app.Dep3) app.Dep4 {
service := app.NewDefaultDep4(Dep1, Dep2, Dep3)
return service
}}
}
func (container *Container) GetDep1() app.Dep1 {
return container.Dep1()
}
func (container *Container) GetDep2() app.Dep2 {
return container.Dep2()
}
func (container *Container) GetDep3() app.Dep3 {
return container.Dep3()
}
func (container *Container) GetDep4() app.Dep4 {
return container.Dep4(container.GetDep1(), container.GetDep2(), container.GetDep3())
}
scope
controls when services are created. One of:
container
(default) - Only created once.prototype
- Always create a new instance.If the returns
returns nil (such as on an error), it is initialised every time because it assumes a nil service is uninitialized.
This is extremely useful when using a factory pattern without needing an extra factory or extra step, like:
services:
Emailer:
type: *SendEmail
scope: prototype
arguments:
- from string
properties:
From: from # Since we can use any Go expression here
Now it can be reused with custom initialization:
emailer := DefaultContainer.GetEmailer("[email protected]")
Hey Eliot you prolong creating nice stuff.
Personally I am pleased to see this repository.
Thanks for that.
So what about problem.
I believe that if we cannot find type, interface and property in time when we parse AST
is a problem and we should notify about that user
At present it is going to be adjourned to compile's message.
if we have such file as this
services:
DoSomething:
type: '*Worker'
interface: Do
properties:
Name: '"Bil"'
If there's no type, interface or property like this, some useful information could be displayed
I haven't tried it, but I assume it would create an infinite recursive loop until go panics.
We should detect circular references when building the container with the dingo
command.
dingo.go
should have the generated code marker so code review and diff programs know to ignore it.
env
is a root level key that lets you set up expressions that can be used with ${}
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.