add Replace di Instance
This commit is contained in:
parent
d90ca3f007
commit
24e307bd32
124
README.md
124
README.md
@ -4,6 +4,8 @@ Go Dependency Injection with Generics
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
### Struct
|
||||||
|
|
||||||
configuration.go
|
configuration.go
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -97,3 +99,125 @@ func main() {
|
|||||||
println(msgService.Welcome())
|
println(msgService.Welcome())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Interface
|
||||||
|
|
||||||
|
message_service.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "git.apihub24.de/admin/generic-di"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
di.Injectable(newMessageService)
|
||||||
|
}
|
||||||
|
|
||||||
|
type IMessageService interface {
|
||||||
|
Welcome() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageService struct {
|
||||||
|
greeter *Greeter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessageService() IMessageService {
|
||||||
|
return &messageService{
|
||||||
|
// here was the Greeter from greeter.go injected
|
||||||
|
greeter: di.Inject[*Greeter](),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *messageService) Welcome() string {
|
||||||
|
return ctx.greeter.Greet()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
main.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import di "git.apihub24.de/admin/generic-di"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
msgService := di.Inject[IMessageService]()
|
||||||
|
// prints the message "Hello, Markus"
|
||||||
|
println(msgService.Welcome())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Replace Instance
|
||||||
|
|
||||||
|
services/message_service.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package services
|
||||||
|
|
||||||
|
import "git.apihub24.de/admin/generic-di"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
di.Injectable(newMessageService)
|
||||||
|
}
|
||||||
|
|
||||||
|
type IMessageService interface {
|
||||||
|
Welcome() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageService struct {
|
||||||
|
greeter *Greeter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessageService() IMessageService {
|
||||||
|
return &messageService{
|
||||||
|
// here was the Greeter from greeter.go injected
|
||||||
|
greeter: di.Inject[*Greeter](),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *messageService) Welcome() string {
|
||||||
|
return ctx.greeter.Greet()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
main.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import di "git.apihub24.de/admin/generic-di"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
msgService := di.Inject[services.IMessageService]()
|
||||||
|
// prints the message "Hello, Markus"
|
||||||
|
println(msgService.Welcome())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
message_service_test.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package services_test
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// replace the instance of IMessageService with the Mock
|
||||||
|
di.Replace(newMessageServiceMock)
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageServiceMock struct {}
|
||||||
|
|
||||||
|
func newMessageServiceMock() services.IMessageService {
|
||||||
|
return &messageServiceMock{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *messageServiceMock) Welcome() string {
|
||||||
|
return "Hello, Mock"
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMessageServiceMocking(t *testing.T) {
|
||||||
|
service := di.Inject[services.IMessageService]()
|
||||||
|
if service.Welcome() != "Hello, Mock" {
|
||||||
|
t.Errorf("expect Hello, Mock but get %s", service.Welcome())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
16
injector.go
16
injector.go
@ -21,6 +21,22 @@ func Injectable[T any](creator func() T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Replace[T any](creator func() T, identifier ...string) {
|
||||||
|
Injectable(creator)
|
||||||
|
selector := getSelector[T]()
|
||||||
|
instanceSelector := getSelector[T](identifier...)
|
||||||
|
cre, creatorExists := creators[selector]
|
||||||
|
if !creatorExists {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createdInstance, instanceCreated := cre().(T)
|
||||||
|
if instanceCreated {
|
||||||
|
instanceMutex.Lock()
|
||||||
|
defer instanceMutex.Unlock()
|
||||||
|
instances[instanceSelector] = createdInstance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Inject gets or create a Instance of the Struct used the Injectable constructor Function
|
// Inject gets or create a Instance of the Struct used the Injectable constructor Function
|
||||||
func Inject[T any](identifier ...string) T {
|
func Inject[T any](identifier ...string) T {
|
||||||
var nilResult T
|
var nilResult T
|
||||||
|
|||||||
@ -13,6 +13,7 @@ func init() {
|
|||||||
di.Injectable(newMessageService)
|
di.Injectable(newMessageService)
|
||||||
di.Injectable(newConfiguration)
|
di.Injectable(newConfiguration)
|
||||||
di.Injectable(newGreetingService)
|
di.Injectable(newGreetingService)
|
||||||
|
di.Injectable(newBasicOverridableService)
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -30,8 +31,33 @@ type (
|
|||||||
Greeting() string
|
Greeting() string
|
||||||
TakeID() string
|
TakeID() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overridableService interface {
|
||||||
|
GetInstanceID() string
|
||||||
|
GetValue() string
|
||||||
|
}
|
||||||
|
|
||||||
|
basicOverridableService struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
basicOverridableServiceMock struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func newBasicOverridableService() overridableService {
|
||||||
|
return &basicOverridableService{
|
||||||
|
id: uuid.NewString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBasicOverridableServiceMock() overridableService {
|
||||||
|
return &basicOverridableServiceMock{
|
||||||
|
id: uuid.NewString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newConfiguration() *configuration {
|
func newConfiguration() *configuration {
|
||||||
return &configuration{}
|
return &configuration{}
|
||||||
}
|
}
|
||||||
@ -53,6 +79,22 @@ func newMessageService() *messageService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *basicOverridableService) GetInstanceID() string {
|
||||||
|
return ctx.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *basicOverridableService) GetValue() string {
|
||||||
|
return "i am original"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *basicOverridableServiceMock) GetInstanceID() string {
|
||||||
|
return ctx.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *basicOverridableServiceMock) GetValue() string {
|
||||||
|
return "i am mock"
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx *configuration) GetUserName() string {
|
func (ctx *configuration) GetUserName() string {
|
||||||
return "Markus"
|
return "Markus"
|
||||||
}
|
}
|
||||||
@ -134,6 +176,22 @@ func TestTryInterface_MultipleInstances(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOverwriteInjectable(t *testing.T) {
|
||||||
|
basic := di.Inject[overridableService]()
|
||||||
|
basicID := basic.GetInstanceID()
|
||||||
|
if basic.GetValue() != "i am original" {
|
||||||
|
t.Errorf("wrong service instance get")
|
||||||
|
}
|
||||||
|
di.Replace(newBasicOverridableServiceMock)
|
||||||
|
basic = di.Inject[overridableService]()
|
||||||
|
if basic.GetInstanceID() == basicID {
|
||||||
|
t.Errorf("basic and newOne are the same instance")
|
||||||
|
}
|
||||||
|
if basic.GetValue() != "i am mock" {
|
||||||
|
t.Errorf("service not overwritten")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDestroy(t *testing.T) {
|
func TestDestroy(t *testing.T) {
|
||||||
_ = di.Inject[textService]("a")
|
_ = di.Inject[textService]("a")
|
||||||
di.Destroy[textService]("a")
|
di.Destroy[textService]("a")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user