Skip to content

Commit

Permalink
feat: adding the package abstraction + doc
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed May 6, 2024
1 parent 3158e2c commit 11f131f
Show file tree
Hide file tree
Showing 8 changed files with 505 additions and 31 deletions.
34 changes: 30 additions & 4 deletions docs/docs/container/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,39 @@ For a quick start, you may use the default global container. This is highly disc
```go
import "github.com/samber/do/v2"

Provide(nil, ...)
Invoke(nil, ...)
do.Provide(nil, ...)
do.Invoke(nil, ...)

// equal to:

Provide(do.DefaultRootScope, ...)
Invoke(do.DefaultRootScope, ...)
do.Provide(do.DefaultRootScope, ...)
do.Invoke(do.DefaultRootScope, ...)
```

## Register services on container initialization

The services can be assembled into a package, and then, imported all at once into a new container.

```go
// pkg/stores/package.go

var Package = do.Package(
do.Lazy(NewPostgresqlConnectionService),
do.Lazy(NewUserRepository),
do.Lazy(NewArticleRepository),
do.EagerNamed("repository.logger", slog.New(slog.NewTextHandler(os.Stdout, nil))),
)
```

```go
// cmd/main.go

import (
"example/pkg/stores"
"example/pkg/handlers"
)

injector := do.New(stores.Package)
```

## Custom options
Expand Down
54 changes: 54 additions & 0 deletions docs/docs/service-registration/package-loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: Package loading
description: Package loading groups multiple service registrations.
sidebar_position: 4
---

# Package loading

Package loading groups multiple service registrations.

## Registration

The services can be assembled into a package, and then, exported all at once.

```go
// pkg/stores/package.go

var Package = do.Package(
do.Lazy(NewPostgresqlConnectionService),
do.Lazy(NewUserRepository),
do.Lazy(NewArticleRepository),
do.EagerNamed("repository.logger", slog.New(slog.NewTextHandler(os.Stdout, nil))),
)
```

```go
// cmd/main.go

import (
"example/pkg/stores"
"example/pkg/handlers"
)

func main() {
injector := do.New(stores.Package)
// ...

// optional scope:
scope := injector.Scope("handlers", handlers.Package)

// ...
}
```

The traditional vocab can be translated for service registration:

- `Provide[T](Injector)` -> `Lazy(T)`
- `ProvideNamed[T](Injector, string)` -> `LazyNamed(string, T)`
- `ProvideValue(Injector, T)` -> `Eager(T)`
- `ProvideNamedValue[T](Injector, string, T)` -> `EagerNamed(string, T)`
- `ProvideTransient[T](Injector)` -> `Transient(T)`
- `ProvideNamedTransient[T](Injector, string)` -> `TransientNamed(string, T)`
- `As[Initial, Alias](Injector)` -> `Bind[Initial, Alias]()`
- `AsNamed[Initial, Alias](Injector, string, string)` -> `BindNamed[Initial, Alias](string, string)`
2 changes: 1 addition & 1 deletion injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Injector interface {
// api
ID() string
Name() string
Scope(string) *Scope
Scope(string, ...func(Injector)) *Scope
RootScope() *RootScope
Ancestors() []*Scope
Children() []*Scope
Expand Down
57 changes: 57 additions & 0 deletions package.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package do

func Package(services ...func(i Injector)) func(Injector) {
return func(injector Injector) {
for i := range services {
services[i](injector)
}
}
}

func Lazy[T any](p Provider[T]) func(Injector) {
return func(injector Injector) {
Provide(injector, p)
}
}

func LazyNamed[T any](serviceName string, p Provider[T]) func(Injector) {
return func(injector Injector) {
ProvideNamed(injector, serviceName, p)
}
}

func Eager[T any](value T) func(Injector) {
return func(injector Injector) {
ProvideValue(injector, value)
}
}

func EagerNamed[T any](serviceName string, value T) func(Injector) {
return func(injector Injector) {
ProvideNamedValue(injector, serviceName, value)
}
}

func Transient[T any](p Provider[T]) func(Injector) {
return func(injector Injector) {
ProvideTransient(injector, p)
}
}

func TransientNamed[T any](serviceName string, p Provider[T]) func(Injector) {
return func(injector Injector) {
ProvideNamedTransient(injector, serviceName, p)
}
}

func Bind[Initial any, Alias any]() func(Injector) {
return func(injector Injector) {
MustAs[Initial, Alias](injector)
}
}

func BindNamed[Initial any, Alias any](initial string, alias string) func(Injector) {
return func(injector Injector) {
MustAsNamed[Initial, Alias](injector, initial, alias)
}
}
Loading

0 comments on commit 11f131f

Please sign in to comment.