Skip to content

Commit

Permalink
rename files/directories matching 'wire' to 'autowire'
Browse files Browse the repository at this point in the history
  • Loading branch information
dabbertorres committed Aug 21, 2021
1 parent d07cde0 commit d2525f1
Show file tree
Hide file tree
Showing 408 changed files with 1,365 additions and 1,206 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This is the official list of Wire authors for copyright purposes.
# This is the official list of (original) Wire authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.

Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# This is the official list of people who can contribute
# (and typically have contributed) code to the Wire repository.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
# (and typically have contributed) code to the (original) Wire
# repository. The AUTHORS file lists the copyright holders; this
# file lists people. For example, Google employees are listed
# here but not in AUTHORS, because Google holds the copyright.
#
# Names should be added to this file only after verifying that
# the individual or the individual's organization has agreed to
Expand Down
135 changes: 68 additions & 67 deletions _tutorial/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Wire Tutorial
# Autowire Tutorial

Let's learn to use Wire by example. The [Wire guide][guide] provides thorough
documentation of the tool's usage. For readers eager to see Wire applied to a
larger server, the [guestbook sample in Go Cloud][guestbook] uses Wire to
Let's learn to use Autowire by example. The [Autowire guide][guide] provides thorough
documentation of the tool's usage. For readers eager to see Autowire applied to a
larger server, the [guestbook sample in Go Cloud][guestbook] uses Autowire to
initialize its components. Here we are going to build a small greeter program to
understand how to use Wire. The finished product may be found in the same
understand how to use Autowire. The finished product may be found in the same
directory as this README.

[guestbook]: https://github.com/google/go-cloud/tree/master/samples/guestbook
[guide]: https://github.com/google/wire/blob/master/docs/guide.md
[guide]: https://github.com/google/autowire/blob/master/docs/guide.md

## A First Pass of Building the Greeter Program

Expand Down Expand Up @@ -88,7 +88,7 @@ The `Start` method holds the core of our small application: it tells the
greeter to issue a greeting and then prints that message to the screen.

Now that we have all the components of our application ready, let's see what it
takes to initialize all the components without using Wire. Our main function
takes to initialize all the components without using Autowire. Our main function
would look like this:

``` go
Expand All @@ -112,10 +112,10 @@ dependency with another.

[di]: https://stackoverflow.com/questions/130794/what-is-dependency-injection

## Using Wire to Generate Code
## Using Autowire to Generate Code

One downside to dependency injection is the need for so many initialization
steps. Let's see how we can use Wire to make the process of initializing our
steps. Let's see how we can use Autowire to make the process of initializing our
components smoother.

Let's start by changing our `main` function to look like this:
Expand All @@ -128,53 +128,54 @@ func main() {
}
```

Next, in a separate file called `wire.go` we will define `InitializeEvent`.
Next, in a separate file called `autowire.go` we will define `InitializeEvent`.
This is where things get interesting:

``` go
// wire.go
// autowire.go

func InitializeEvent() Event {
wire.Build(NewEvent, NewGreeter, NewMessage)
autowire.Build(NewEvent, NewGreeter, NewMessage)
return Event{}
}
```

Rather than go through the trouble of initializing each component in turn and
passing it into the next one, we instead have a single call to `wire.Build`
passing in the initializers we want to use. In Wire, initializers are known as
passing it into the next one, we instead have a single call to `autowire.Build`
passing in the initializers we want to use. In Autowire, initializers are known as
"providers," functions which provide a particular type. We add a zero value for
`Event` as a return value to satisfy the compiler. Note that even if we add
values to `Event`, Wire will ignore them. In fact, the injector's purpose is to
values to `Event`, Autowire will ignore them. In fact, the injector's purpose is to
provide information about which providers to use to construct an `Event` and so
we will exclude it from our final binary with a build constraint at the top of
the file:

``` go
//+build wireinject
//go:build wireinject

```

Note, a [build constraint][constraint] requires a blank, trailing line.

In Wire parlance, `InitializeEvent` is an "injector." Now that we have our
injector complete, we are ready to use the `wire` command line tool.
In Autowire parlance, `InitializeEvent` is an "injector." Now that we have our
injector complete, we are ready to use the `autowire` command line tool.

Install the tool with:

``` shell
go get github.com/google/wire/cmd/wire
go get github.com/dabbertorres/autowire/cmd/autowire
```

Then in the same directory with the above code, simply run `wire`. Wire will
Then in the same directory with the above code, simply run `autowire`. Autowire will
find the `InitializeEvent` injector and generate a function whose body is
filled out with all the necessary initialization steps. The result will be
written to a file named `wire_gen.go`.
written to a file named `autowire_gen.go`.

Let's take a look at what Wire did for us:
Let's take a look at what Autowire did for us:

``` go
// wire_gen.go
// autowire_gen.go

func InitializeEvent() Event {
message := NewMessage()
Expand All @@ -186,14 +187,14 @@ func InitializeEvent() Event {

It looks just like what we wrote above! Now this is a simple example with just
three components, so writing the initializer by hand isn't too painful. Imagine
how useful Wire is for components that are much more complex. When working with
Wire, we will commit both `wire.go` and `wire_gen.go` to source control.
how useful Autowire is for components that are much more complex. When working with
Autowire, we will commit both `autowire.go` and `autowire_gen.go` to source control.

[constraint]: https://godoc.org/go/build#hdr-Build_Constraints

## Making Changes with Wire
## Making Changes with Autowire

To show a small part of how Wire handles more complex setups, let's refactor
To show a small part of how Autowire handles more complex setups, let's refactor
our initializer for `Event` to return an error and see what happens.

``` go
Expand Down Expand Up @@ -251,21 +252,21 @@ func main() {
We also need to update `InitializeEvent` to add an `error` type to the return value:

``` go
// wire.go
// autowire.go

func InitializeEvent() (Event, error) {
wire.Build(NewEvent, NewGreeter, NewMessage)
autowire.Build(NewEvent, NewGreeter, NewMessage)
return Event{}, nil
}
```

With the setup complete, we are ready to invoke the `wire` command again. Note,
that after running `wire` once to produce a `wire_gen.go` file, we may also use
`go generate`. Having run the command, our `wire_gen.go` file looks like
With the setup complete, we are ready to invoke the `autowire` command again. Note,
that after running `autowire` once to produce a `autowire_gen.go` file, we may also use
`go generate`. Having run the command, our `autowire_gen.go` file looks like
this:

``` go
// wire_gen.go
// autowire_gen.go

func InitializeEvent() (Event, error) {
message := NewMessage()
Expand All @@ -278,21 +279,21 @@ func InitializeEvent() (Event, error) {
}
```

Wire has detected that the `NewEvent` provider may fail and has done the right
Autowire has detected that the `NewEvent` provider may fail and has done the right
thing inside the generated code: it checks the error and returns early if one
is present.

## Changing the Injector Signature

As another improvement, let's look at how Wire generates code based on the
As another improvement, let's look at how Autowire generates code based on the
signature of the injector. Presently, we have hard-coded the message inside
`NewMessage`. In practice, it's much nicer to allow callers to change that
message however they see fit. So let's change `InitializeEvent` to look like
this:

``` go
func InitializeEvent(phrase string) (Event, error) {
wire.Build(NewEvent, NewGreeter, NewMessage)
autowire.Build(NewEvent, NewGreeter, NewMessage)
return Event{}, nil
}
```
Expand All @@ -306,12 +307,12 @@ func NewMessage(phrase string) Message {
}
```

After we run `wire` again, we will see that the tool has generated an
After we run `autowire` again, we will see that the tool has generated an
initializer which passes the `phrase` value as a `Message` into `Greeter`.
Neat!

``` go
// wire_gen.go
// autowire_gen.go

func InitializeEvent(phrase string) (Event, error) {
message := NewMessage(phrase)
Expand All @@ -324,44 +325,44 @@ func InitializeEvent(phrase string) (Event, error) {
}
```

Wire inspects the arguments to the injector, sees that we added a string to the
Autowire inspects the arguments to the injector, sees that we added a string to the
list of arguments (e.g., `phrase`), and likewise sees that among all the
providers, `NewMessage` takes a string, and so it passes `phrase` into
`NewMessage`.

## Catching Mistakes with Helpful Errors

Let's also look at what happens when Wire detects mistakes in our code and see
how Wire's error messages help us correct any problems.
Let's also look at what happens when Autowire detects mistakes in our code and see
how Autowire's error messages help us correct any problems.

For example, when writing our injector `InitializeEvent`, let's say we forget
to add a provider for `Greeter`. Let's see what happens:

``` go
func InitializeEvent(phrase string) (Event, error) {
wire.Build(NewEvent, NewMessage) // woops! We forgot to add a provider for Greeter
autowire.Build(NewEvent, NewMessage) // woops! We forgot to add a provider for Greeter
return Event{}, nil
}
```

Running `wire`, we see the following:
Running `autowire`, we see the following:

``` shell
# wrapping the error across lines for readability
$GOPATH/src/github.com/google/wire/_tutorial/wire.go:24:1:
inject InitializeEvent: no provider found for github.com/google/wire/_tutorial.Greeter
(required by provider of github.com/google/wire/_tutorial.Event)
wire: generate failed
$GOPATH/src/github.com/google/autowire/_tutorial/autowire.go:24:1:
inject InitializeEvent: no provider found for github.com/google/autowire/_tutorial.Greeter
(required by provider of github.com/google/autowire/_tutorial.Event)
autowire: generate failed
```

Wire is telling us some useful information: it cannot find a provider for
Autowire is telling us some useful information: it cannot find a provider for
`Greeter`. Note that the error message prints out the full path to the
`Greeter` type. It's also telling us the line number and injector name where
the problem occurred: line 24 inside `InitializeEvent`. In addition, the error
message tells us which provider needs a `Greeter`. It's the `Event` type. Once
we pass in a provider of `Greeter`, the problem will be solved.

Alternatively, what happens if we provide one too many providers to `wire.Build`?
Alternatively, what happens if we provide one too many providers to `autowire.Build`?

``` go
func NewEventNumber() int {
Expand All @@ -370,50 +371,50 @@ func NewEventNumber() int {

func InitializeEvent(phrase string) (Event, error) {
// woops! NewEventNumber is unused.
wire.Build(NewEvent, NewGreeter, NewMessage, NewEventNumber)
autowire.Build(NewEvent, NewGreeter, NewMessage, NewEventNumber)
return Event{}, nil
}
```

Wire helpfully tells us that we have an unused provider:
Autowire helpfully tells us that we have an unused provider:

``` shell
$GOPATH/src/github.com/google/wire/_tutorial/wire.go:24:1:
$GOPATH/src/github.com/google/autowire/_tutorial/autowire.go:24:1:
inject InitializeEvent: unused provider "NewEventNumber"
wire: generate failed
autowire: generate failed
```

Deleting the unused provider from the call to `wire.Build` resolves the error.
Deleting the unused provider from the call to `autowire.Build` resolves the error.

## Conclusion

Let's summarize what we have done here. First, we wrote a number of components
with corresponding initializers, or providers. Next, we created an injector
function, specifying which arguments it receives and which types it returns.
Then, we filled in the injector function with a call to `wire.Build` supplying
all necessary providers. Finally, we ran the `wire` command to generate code
Then, we filled in the injector function with a call to `autowire.Build` supplying
all necessary providers. Finally, we ran the `autowire` command to generate code
that wires up all the different initializers. When we added an argument to the
injector and an error return value, running `wire` again made all the necessary
injector and an error return value, running `autowire` again made all the necessary
updates to our generated code.

The example here is small, but it demonstrates some of the power of Wire, and
The example here is small, but it demonstrates some of the power of Autowire, and
how it takes much of the pain out of initializing code using dependency
injection. Furthermore, using Wire produced code that looks much like what we
would otherwise write. There are no bespoke types that commit a user to Wire.
injection. Furthermore, using Autowire produced code that looks much like what we
would otherwise write. There are no bespoke types that commit a user to Autowire.
Instead it's just generated code. We may do with it what we will. Finally,
another point worth considering is how easy it is to add new dependencies to
our component initialization. As long as we tell Wire how to provide (i.e.,
our component initialization. As long as we tell Autowire how to provide (i.e.,
initialize) a component, we may add that component anywhere in the dependency
graph and Wire will handle the rest.
graph and Autowire will handle the rest.

In closing, it is worth mentioning that Wire supports a number of additional
In closing, it is worth mentioning that Autowire supports a number of additional
features not discussed here. Providers may be grouped in [provider sets][sets].
There is support for [binding interfaces][interfaces], [binding
values][values], as well as support for [cleanup functions][cleanup]. See the
[Advanced Features][advanced] section for more.

[advanced]: https://github.com/google/wire/blob/master/docs/guide.md#advanced-features
[cleanup]: https://github.com/google/wire/blob/master/docs/guide.md#cleanup-functions
[interfaces]: https://github.com/google/wire/blob/master/docs/guide.md#binding-interfaces
[sets]: https://github.com/google/wire/blob/master/docs/guide.md#defining-providers
[values]: https://github.com/google/wire/blob/master/docs/guide.md#binding-values
[advanced]: https://github.com/google/autowire/blob/master/docs/guide.md#advanced-features
[cleanup]: https://github.com/google/autowire/blob/master/docs/guide.md#cleanup-functions
[interfaces]: https://github.com/google/autowire/blob/master/docs/guide.md#binding-interfaces
[sets]: https://github.com/google/autowire/blob/master/docs/guide.md#defining-providers
[values]: https://github.com/google/autowire/blob/master/docs/guide.md#binding-values
1 change: 1 addition & 0 deletions _tutorial/wire.go → _tutorial/autowire.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

//+build wireinject
//go:build wireinject

// The build tag makes sure the stub is not built in the final build.
package main
Expand Down
5 changes: 3 additions & 2 deletions _tutorial/wire_gen.go → _tutorial/autowire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d2525f1

Please sign in to comment.