![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
github.com/defval/inject
Dependency injection container allows you to inject dependencies into constructors or structures without the need to have specified each argument manually.
This container implementation inspired by google/wire, uber-go/fx and uber-go/dig.
See godoc for feel the difference.
go get -u github.com/defval/inject
Define constructors:
// NewHTTPHandler is a http mux constructor.
func NewHTTPServeMux() *http.ServeMux {
return &http.ServeMux{}
}
// NewHTTPServer is a http server constructor, handler will be injected
// by container. If environment variable `STATUS == "stoped"` extract
// server cause error.
func NewHTTPServer(handler *net.ServeMux) (*http.Server, error) {
if os.Getenv("STATUS") == "stopped" {
return nil, errors.New("server stoped")
}
return &http.Server{
Handler: handler,
}, nil
}
Build container and extract values:
// build container
container, err := inject.New(
inject.Provide(NewHTTPServeMux), // provide mux
inject.Provide(NewHTTPServer), // provide server
)
// don't forget to handle errors © golang
// define variable for *http.Server
var server *http.Server
// extract into this variable
container.Extract(&server)
// use it!
server.ListenAndServe()
When you have two or more implementations of same interface:
// NewUserController
func NewUserController() *UserController {
return &UserController{}
}
// NewPostController
func NewPostController() *PostController {
return &PostController()
}
// Controller
type Controller interface {
RegisterRoutes()
}
Group it!
// IController is a java style interface alias =D
// inject.As(new(Controller)) looks worse in readme.
var IController = new(Controller)
container, err := inject.New(
inject.Provide(NewUserController, inject.As(IController)),
inject.Provide(NewPostController, inject.As(IController)),
)
var controllers []Controller
// extract all controllers
container.Extract(&controllers)
// and do something!!!
for _, ctrl := range controllers {
ctrl.RegisterRoutes()
}
Bind implementations as interfaces:
// NewHandler is a http mux constructor. Returns concrete
// implementation - *http.ServeMux.
func NewServeMux() *http.ServeMux {
return &http.ServeMux{}
}
// NewServer is a http server constructor. Needs handler for
// working.
func NewServer(handler http.Handler) *http.Server {
return &http.Server{
Handler: handler,
}
}
Provide concrete implementation as interface:
var IHandler = new(http.Handler)
container, err := inject.New(
inject.Provide(NewServeMux, inject.As(IHandler)),
inject.Provide(NewServer),
)
var handler http.Handler
container.Extract(&handler) // *http.ServeMux will be extracted
var server *http.Server
container.Extract(&server) // server.Handler is *http.ServeMux
// ProcessingBundle responsible for processing
var ProcessingBundle = inject.Bundle(
inject.Provide(processing.NewDispatcher),
inject.Provide(processing.NewProvider),
inject.Provide(processing.NewProxy, inject.As(IProxy)),
)
// BillingBundle responsible for billing
var BillingBundle = inject.Bundle(
inject.Provide(billing.NewInteractor),
inject.Provide(billing.NewInvoiceRepository, inject.As(new(InvoiceRepository)))
)
And test each one separately.
func TestProcessingBundle(t *testing.T) {
bundle, err := inject.New(
ProcessingBundle,
inject.Replace(processing.NewDevProxy, inject.As(IProxy)),
)
var dispatcher *processing.Dispatcher
container.Extract(&dispatcher)
dispatcher.Dispatch(ctx context.Context, thing)
}
var options []inject.Options
if os.Getenv("ENV") == "dev" {
options = append(options, inject.Replace(billing.NewInvoiceRepositoryMock), inject.As(new(InvoiceRepository)))
}
container, err := inject.New(options...)
container, err := inject.New{
inject.Provide(NewDefaultServer, inject.WithName("default")),
inject.Provide(NewAdminServer, inject.WithName("admin")),
}
var defaultServer *http.Server
var adminServer *http.Server
container.Extract(&defaultServer, inject.Name("default"))
container.Extract(&adminServer, inject.Name("admin"))
Or with struct provider:
// Application
type Application struct {
Server *http.Server `inject:"default"`
AdminServer *http.Server `inject:"admin"`
}
container, err := inject.New(
inject.Provide(NewDefaultServer, inject.WithName("default")),
inject.Provide(NewAdminServer, inject.WithName("admin")),
inject.Provide(&Application)
)
If you don't like tags as much as I do, then look to
inject.Exported()
provide option.
For advanced providing use combined provider. It's both - struct and constructor providers.
// ServerProvider
type ServerProvider struct {
Mux *http.Server `inject:"dude_mux"`
}
// Provide is a container predefined constructor function for *http.Server.
func (p *ServerProvider) Provide() *http.Server {
return &http.Server{
Handler: p.Mux,
}
}
Write visualization into io.Writer
. Check out result on graphviz online tool!
// visualization data target
buffer := &bytes.Buffer{}
// write container visualization
container.WriteTo(buffer)
or
// define github.com/emicklei/*dot.Graph type
var graph *dot.Graph
// extract graph
container.Extract(&graph)
// use
graph.Write(buffer)
This is visualization of container example.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.