-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the first release and contains enough to get started.
- Loading branch information
0 parents
commit 479a901
Showing
17 changed files
with
1,093 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, build with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
/.idea | ||
/dingo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2019 Elliot Chance | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# 🐺 dingo | ||
|
||
Easy, fast and type-safe dependency injection for Go. | ||
|
||
* [Installation](#installation) | ||
* [Building the Container](#building-the-container) | ||
* [Configuring Services](#configuring-services) | ||
* [Using Services](#using-services) | ||
* [Unit Testing](#unit-testing) | ||
|
||
## Installation | ||
|
||
```bash | ||
go get -u github.com/elliotchance/dingo | ||
``` | ||
|
||
## Building the Container | ||
|
||
Building or rebuilding the container is done with: | ||
|
||
```bash | ||
dingo | ||
``` | ||
|
||
The container is created from a file called `dingo.yml` in the same directory as | ||
where the `dingo` command is run. This should be the root of your | ||
module/repository. | ||
|
||
Here is an example of a `dingo.yml`: | ||
|
||
```yml | ||
services: | ||
SendEmail: | ||
type: *SendEmail | ||
interface: EmailSender | ||
properties: | ||
From: '"[email protected]"' | ||
|
||
CustomerWelcome: | ||
type: *CustomerWelcome | ||
returns: NewCustomerWelcome(@SendEmail) | ||
``` | ||
It will generate a file called `dingo.go`. This must be committed with your | ||
code. | ||
|
||
## Configuring Services | ||
|
||
The `dingo.yml` is described below: | ||
|
||
```yml | ||
services: | ||
# Describes each of the services. The name of the service follow the same | ||
# naming conventions as Go, so service names that start with a capital letter | ||
# will be exported (available outside this package). | ||
SendEmail: | ||
# Required: You must provide either 'type' or 'interface'. | ||
# Optional: The type returned by the `return` expression. You must provide a | ||
# fully qualified name that includes the package name if the type does not | ||
# belong to this package. For example: | ||
# | ||
# type: '*github.com/go-redis/redis.Options' | ||
# | ||
type: *SendEmail | ||
|
||
# Optional: If you need to replace this service with another struct type in | ||
# unit tests you will need to provide an interface. This will override | ||
# `type` and must be compatible with returned type of `return`. | ||
interface: EmailSender | ||
|
||
# Optional: The expression used to instantiate the service. You can provide | ||
# any Go code here, including referencing other services and environment | ||
# variables. Described in more detail below. | ||
returns: NewSendEmail() | ||
|
||
# Optional: If 'returns' provides two arguments (where the second one is the | ||
# error) you must include an 'error'. This is the expression when | ||
# "err != nil". | ||
error: panic(err) | ||
|
||
# Optional: If provided, a map of case-sensitive properties to be set on the | ||
# instance. Each of the properties is Go code and can have the same | ||
# substitutions described below. | ||
properties: | ||
From: "[email protected]" | ||
maxRetries: 10 | ||
|
||
# Optional: You can provide explicit imports if you need to reference | ||
# packages in expressions (such as 'returns') that do not exist 'type' or | ||
# 'interface'. | ||
import: | ||
- 'github.com/aws/aws-sdk-go/aws/session' | ||
``` | ||
The `returns` and properties can contain any Go code, and allows the following | ||
substitutions: | ||
|
||
- `@{SendEmail}` will inject the service named `SendEmail`. | ||
- `${DB_PASS}` will inject the environment variable `DB_PASS`. | ||
|
||
## Using Services | ||
|
||
As part of the generated file, `dingo.go`. There will be a module-level variable | ||
called `DefaultContainer`. This requires no initialization and can be used | ||
immediately: | ||
|
||
```go | ||
func main() { | ||
welcomer := DefaultContainer.GetCustomerWelcome() | ||
err := welcomer.Welcome("Bob", "[email protected]") | ||
// ... | ||
} | ||
``` | ||
|
||
## Unit Testing | ||
|
||
**When unit testing you should not use the global `DefaultContainer`.** You | ||
should create a new container: | ||
|
||
```go | ||
container := &Container{} | ||
``` | ||
|
||
Unit tests can make any modifications to the new container, including overriding | ||
services to provide mocks or other stubs: | ||
|
||
```go | ||
func TestCustomerWelcome_Welcome(t *testing.T) { | ||
emailer := FakeEmailSender{} | ||
emailer.On("Send", | ||
"[email protected]", "Welcome", "Hi, Bob!").Return(nil) | ||
container := &Container{} | ||
container.SendEmail = emailer | ||
welcomer := container.GetCustomerWelcome() | ||
err := welcomer.Welcome("Bob", "[email protected]") | ||
assert.NoError(t, err) | ||
emailer.AssertExpectations(t) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package dingotest | ||
|
||
import "fmt" | ||
|
||
type CustomerWelcome struct { | ||
Emailer EmailSender | ||
} | ||
|
||
func NewCustomerWelcome(sender EmailSender) *CustomerWelcome { | ||
return &CustomerWelcome{ | ||
Emailer: sender, | ||
} | ||
} | ||
|
||
func (welcomer *CustomerWelcome) Welcome(name, email string) error { | ||
body := fmt.Sprintf("Hi, %s!", name) | ||
subject := "Welcome" | ||
|
||
return welcomer.Emailer.Send(email, subject, body) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package dingotest | ||
|
||
import ( | ||
go_sub_pkg "github.com/elliotchance/dingo/dingotest/go-sub-pkg" | ||
"os" | ||
) | ||
|
||
type Container struct { | ||
CustomerWelcome *CustomerWelcome | ||
OtherPkg *go_sub_pkg.Person | ||
OtherPkg2 go_sub_pkg.Greeter | ||
OtherPkg3 *go_sub_pkg.Person | ||
SendEmail EmailSender | ||
SendEmailError *SendEmail | ||
SomeEnv *string | ||
WithEnv1 *SendEmail | ||
WithEnv2 *SendEmail | ||
} | ||
|
||
var DefaultContainer = &Container{} | ||
|
||
func (container *Container) GetCustomerWelcome() *CustomerWelcome { | ||
if container.CustomerWelcome == nil { | ||
service := NewCustomerWelcome(container.GetSendEmail()) | ||
container.CustomerWelcome = service | ||
} | ||
return container.CustomerWelcome | ||
} | ||
func (container *Container) GetOtherPkg() *go_sub_pkg.Person { | ||
if container.OtherPkg == nil { | ||
service := &go_sub_pkg.Person{} | ||
container.OtherPkg = service | ||
} | ||
return container.OtherPkg | ||
} | ||
func (container *Container) GetOtherPkg2() go_sub_pkg.Greeter { | ||
if container.OtherPkg2 == nil { | ||
service := go_sub_pkg.NewPerson() | ||
container.OtherPkg2 = service | ||
} | ||
return container.OtherPkg2 | ||
} | ||
func (container *Container) GetOtherPkg3() go_sub_pkg.Person { | ||
if container.OtherPkg3 == nil { | ||
service := go_sub_pkg.Person{} | ||
container.OtherPkg3 = &service | ||
} | ||
return *container.OtherPkg3 | ||
} | ||
func (container *Container) GetSendEmail() EmailSender { | ||
if container.SendEmail == nil { | ||
service := &SendEmail{} | ||
service.From = "[email protected]" | ||
container.SendEmail = service | ||
} | ||
return container.SendEmail | ||
} | ||
func (container *Container) GetSendEmailError() *SendEmail { | ||
if container.SendEmailError == nil { | ||
service, err := NewSendEmail() | ||
if err != nil { | ||
panic(err) | ||
} | ||
container.SendEmailError = service | ||
} | ||
return container.SendEmailError | ||
} | ||
func (container *Container) GetSomeEnv() string { | ||
if container.SomeEnv == nil { | ||
service := os.Getenv("ShouldBeSet") | ||
container.SomeEnv = &service | ||
} | ||
return *container.SomeEnv | ||
} | ||
func (container *Container) GetWithEnv1() SendEmail { | ||
if container.WithEnv1 == nil { | ||
service := SendEmail{} | ||
service.From = os.Getenv("ShouldBeSet") | ||
container.WithEnv1 = &service | ||
} | ||
return *container.WithEnv1 | ||
} | ||
func (container *Container) GetWithEnv2() *SendEmail { | ||
if container.WithEnv2 == nil { | ||
service := &SendEmail{} | ||
service.From = "foo-" + os.Getenv("ShouldBeSet") + "-bar" | ||
container.WithEnv2 = service | ||
} | ||
return container.WithEnv2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
services: | ||
SendEmail: | ||
type: '*SendEmail' | ||
interface: EmailSender | ||
properties: | ||
From: '"[email protected]"' | ||
|
||
CustomerWelcome: | ||
type: '*CustomerWelcome' | ||
returns: NewCustomerWelcome(@{SendEmail}) | ||
|
||
WithEnv1: | ||
type: SendEmail | ||
properties: | ||
From: ${ShouldBeSet} | ||
|
||
WithEnv2: | ||
type: '*SendEmail' | ||
properties: | ||
From: '"foo-" + ${ShouldBeSet} + "-bar"' | ||
|
||
SomeEnv: | ||
type: string | ||
returns: ${ShouldBeSet} | ||
|
||
OtherPkg: | ||
type: '*github.com/elliotchance/dingo/dingotest/go-sub-pkg.Person' | ||
|
||
OtherPkg2: | ||
type: '*github.com/elliotchance/dingo/dingotest/go-sub-pkg.Person' | ||
interface: github.com/elliotchance/dingo/dingotest/go-sub-pkg.Greeter | ||
returns: go_sub_pkg.NewPerson() | ||
|
||
OtherPkg3: | ||
type: github.com/elliotchance/dingo/dingotest/go-sub-pkg.Person | ||
|
||
SendEmailError: | ||
type: '*SendEmail' | ||
returns: NewSendEmail() | ||
error: panic(err) |
Oops, something went wrong.