Package di is an dependency injection container implements. Source code and other details for the project are available at GitHub:
Package glue provides a simple interface to writing HTTP services in Go It aims to be small and as simple as possible while exposing a pleasant API. Glue uses reflection and dependency injection to provide a flexible API for your HTTP endpoints. There is an obvious tradeoff here. The cost of this flexibility is some static safety and some performance overhead (though this appears negligible in benchmarking). godoc: http://godoc.org/github.com/tmc/glue Features: Basic Example: Example showing middleware, logging, routing, and static file serving: glue is influenced by martini and basically co-opts gorilla's pat muxing for routing.
The state package provides simple state management primitives for go applications. The package defines the State type, which carries errors, wait groups, shutdown signals and other values from application's background jobs. The State type is aggregative - it contains multiple states in tree form, allowing setting dependencies for graceful shutdown between them and merging multiple independent states. To aggregate the application's states, functions that initialize background jobs create suitable State and propagate it up in the calls stack to the layer where it will be handled, optionally merging it with other states, setting dependencies between them and annotating along the way. Programs that use State should follow these rules to keep interfaces consistent: 1. All functions that initialize application-scoped background jobs should return State as its last return value. There might be special cases, when returning state as the last return value is not possible, for example - when using dependency injection packages. To handle this case, embed State into dependency's return value: 2. If an error can occur during initialization it is still should be returned as State using function WithError. 3. Never return nil State - return Empty() instead, or do not return State at all if it is not needed. 4. Every background job should be shutdownable and/or waitable.
Package dipper is a small dependency injection library
Package infra provides cloud infrastructure management for Go programs. The package includes facilities for configuring, provisioning, and migrating cloud infrastructure that is used by a Go program. You can think of infra as a simple, embedded version of Terraform, combined with a self-contained dependency injection framework. Infrastructure managed by this package is exposed through a configuration. Configurations specify which providers should be used for which infrastructure component; configurations also store provider configuration and migration state. Users instantiate typed values directly from the configuration: the details of configuration and of managing dependencies between infrastructure components is handled by the config object itself. Configurations are marshaled and must be stored by the user. Infrastructure migration is handled by maintaining a set of versions for each provider; migrations perform side-effects and can modify the configuration accordingly (e.g., to store identifiers used by the cloud infrastructure provider).
Package inject provides utilities for mapping and injecting dependencies in various ways.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package container provides an IoC container for Go projects. It provides simple, fluent and easy-to-use interface to make dependency injection in GoLang easier.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package fx is a framework that makes it easy to build applications out of reusable, composable modules. Fx applications use dependency injection to eliminate globals without the tedium of manually wiring together function calls. Unlike other approaches to dependency injection, Fx works with plain Go functions: you don't need to use struct tags or embed special types, so Fx automatically works well with most Go packages. Basic usage is explained in the package-level example below. If you're new to Fx, start there! Advanced features, including named instances, optional parameters, and value groups, are explained under the In and Out types. To test functions that use the Lifecycle type or to write end-to-end tests of your Fx application, use the helper functions and types provided by the go.uber.org/fx/fxtest package.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package izidic defines a tiny dependency injection container. The basic feature is that storing service definitions does not create instances, allowing users to store definitions of services requiring other services before those are actually defined. Container writes are not concurrency-safe, so they are locked with Container.Freeze() after the initial setup, which is assumed to be non-concurrent.
Package fx is a framework that makes it easy to build applications out of reusable, composable modules. Fx applications use dependency injection to eliminate globals without the tedium of manually wiring together function calls. Unlike other approaches to dependency injection, Fx works with plain Go functions: you don't need to use struct tags or embed special types, so Fx automatically works well with most Go packages. Basic usage is explained in the package-level example below. If you're new to Fx, start there! Advanced features, including named instances, optional parameters, and value groups, are explained under the In and Out types. To test functions that use the Lifecycle type or to write end-to-end tests of your Fx application, use the helper functions and types provided by the go.uber.org/fx/fxtest package.
Package xstats is a generic client for service instrumentation. xstats is inspired from Go-kit's metrics (https://github.com/go-kit/kit/tree/master/metrics) package but it takes a slightly different path. Instead of having to create an instance for each metric, xstats use a single instance to log every metrics you want. This reduces the boiler plate when you have a lot a metrics in your app. It's also easier in term of dependency injection. Talking about dependency injection, xstats comes with a xhandler.Handler integration so it can automatically inject the xstats client within the net/context of each request. Each request's xstats instance have its own tags storage ; This let you inject some per request contextual tags to be included with all observations sent within the lifespan of the request. xstats is pluggable and comes with integration for StatsD and DogStatsD, the Datadog (http://datadoghq.com) augmented version of StatsD with support for tags. More integration may come later (PR welcome).
Package wrap creates a fast and flexible middleware stack for http.Handlers. Each middleware is a wrapper for another middleware and implements the Wrapper interface. Features Wrappers can be found at http://godoc.org/github.com/go-on/wrap-contrib/wraps. A (mountable) router that plays fine with wrappers can be found at http://godoc.org/github.com/go-on/router. Benchmarks (Go 1.3) Initial inspiration came from Christian Neukirchen's rack for ruby some years ago. The core of this package is the New function that constructs a stack of middlewares that implement the Wrapper interface. If the global DEBUG flag is set before calling New then each middleware call will result in calling the Debug method of the global DEBUGGER (defaults to a logger). To help constructing middleware there are some adapters like WrapperFunc, Handler, HandlerFunc, NextHandler and NextHandlerFunc each of them adapting to the Wrapper interface. To help sharing per request context there is a Contexter interface that must be implemented by the ResponseWriter. That can easily be done be providing a middleware that injects a context that wraps the current ResponseWriter and implements the Contexter interface. It must a least support the extraction of the wrapped ResponseWriter. Then there are functions to validate implementations of Contexter (ValidateContextInjecter) and to validate them against wrappers that store and retrieve the context data (ValidateWrapperContexts). An complete example for shared contexts can be found in the file example_context_test.go. Furthermore this package provides some ResponseWriter wrappers that also implement Contexter and that help with development of middleware. These are Buffer, Peek and EscapeHTML. Buffer is a simple buffer. A middleware may pass it to the next handlers ServeHTTP method as a drop in replacement for the response writer. After the ServeHTTP method is run the middleware may examine what has been written to the Buffer and decide what to write to the "original" ResponseWriter (that may well be another buffer passed from another middleware). The downside is the body being written two times and the complete caching of the body in the memory which will be inacceptable for large bodies. Therefor Peek is an alternative response writer wrapper that only caching headers and status code but allowing to intercept calls of the Write method. All middleware without the need to read the whole response body should use Peek or provide their own ResponseWriter wrapper (then do not forget to implement the Contexter interface). Finally EscapeHTML provides a response writer wrapper that allows on the fly html escaping of the bytes written to the wrapped response writer. It is pretty easy to write your custom middleware. You should start with a new struct type - that allows you to add options as fields later on. Then you could use the following template to implement the Wrapper interface If you need to run the next handler in order to inspect what it did, replace the response writer with a Peek (see NewPeek) or if you need full access to the written body with a Buffer. To form a middleware stack, simply use New() and pass it the middlewares. They get the request top-down. There are some adapters to let for example a http.Handler be a middleware (Wrapper) that does not call the next handler and stops the chain. To use per request context a custom type is needed that carries the context data and the user is expected to create and inject a Contexter supporting this type. Here is a template for a middleware that you could use to write middleware that wants to use / share context. For context sharing the user has to implement the Contexter interface in a way that supports all types the used middlewares expect. Here is a template for an implementation of the Contexter interface At any time there must be only one Contexter in the whole middleware stack and its the best to let it be the first middleware. Then you don't have to worry if its there or not (the Stack function might help you). The corresponding middleware stack would look like this If your application / handler also uses context data, it is a good idea to implement it as ContextWrapper as if it were a middleware and pass it ValidateWrapperContexts(). So if your context is wrong, you will get nice panics before your server even starts. And this is always in sync with your app / middleware. If for some reason the original ResponseWriter is needed (to type assert it to a http.Flusher for example), it may be reclaimed with the help of ReclaimResponseWriter(). You might want to look at existing middlewares to get some ideas: http://godoc.org/github.com/go-on/wrap-contrib/wraps 1. Should the context not better be an argument to a middleware function, to make this dependency visible in documentation and tools? Answer: A unified interface gives great freedom when organizing and ordering middleware as the middleware in between does not have to know about a certain context type if does not care about it. It simply passes the ResponseWriter that happens to have context down the middleware stack chain. On the other hand, exposing the context type by making it a parameter has the effect that every middleware will need to pass this parameter to the next one if the next one needs it. Every middleware is then tightly coupled to the next one and reordering or mixing of middleware from different sources becomes impossible. However with the ContextHandler interface and the ValidateWrapperContexts function we have a way to guarantee that the requirements are met. And this solution is also type safe. 2. A ResponseWriter is an interface, because it may implement other interfaces from the http libary, e.g. http.Flusher. If it is wrapped that underlying implementation is not accessible anymore Answer: When the Contexter is validated, it is checked, that the Context method supports http.ResponseWriter as well (and that it returns the underlying ResponseWriter). Since only one Contexter may be used within a stack, it is always possible to ask the Contexter for the underlying ResponseWriter. This is what helper functions like ReclaimResponseWriter(), Flush(), CloseNotify() and Hijack() do. 3. Why is the recommended way to use the Contexter interface to make a type assertion from the ResponseWriter to the Contexter interface without error handling? Answer: Middleware stacks should be created before the server is handling requests and then not change anymore. And you should run tests. Then the assertion will blow up and that is correct because there is no reasonable way to handle such an error. It means that either you have no context in your stack or you inject the context to late or the context does not handle the kind of type the middleware expects. In each case you should fix it early and the panic forces you to do. Use the DEBUG flag to see what's going on. 4. What happens if my context is wrapped inside another context or response writer? Answer: You should only have one Contexter per application and inject it as first wrapper into your middleware stack. All context specific data belongs there. Having multiple Contexter in a stack is considered a bug. The good news is that you now can be sure to be able to access all of your context data everywhere inside your stack. Never should a context wrap another one. There also should be no need for another context wrapping ResponseWriter because every type can be saved by a Contexter with few code. All response writer wrappers of this package implement the Contexter interface and every response writer you use should. 5. Why isn't there any default context object? Why do I have to write it on my own? Answer: To write your own context and context injection has several benefits: 6. Why is the context data accessed and stored via type switch and not by string keys? Answer: Type based context allows a very simple implementation that namespaces across packages needs no extra memory allocation and is, well, type safe. If you need to store multiple context data of the same type, simple defined an alias type for each key. 7. Is there an example how to integrate with 3rd party middleware libraries that expect context? Answer: Yes, have a look at http://godoc.org/github.com/go-on/wrap-contrib/third-party. 8. What about spawning goroutines / how does it relate to code.google.com/p/go.net/context? If you need your request to be handled by different goroutines and middlewares you might use your Contexter to store and provide access to a code.google.com/p/go.net/context Context just like any other context data. The good news is that you can write you middleware like before and extract your Context everywhere you need it. And if you have middleware in between that does not know about about Context or other context data you don't have build wrappers around that have Context as parameter. Instead the ResponseWriter that happens to provide you a Context will be passed down the chain by the middleware. "At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests." (Sameer Ajmani, http://blog.golang.org/context) This is not neccessary anymore. And it is not neccessary for any type of contextual data because that does not have to be in the type signature anymore.
Package izidic defines a tiny dependency injection container. The basic feature is that storing service definitions does not create instances, allowing users to store definitions of services requiring other services before those are actually defined. Container writes are not concurrency-safe, so they are locked with Container.Freeze() after the initial setup, which is assumed to be non-concurrent
Package iris implements the highest realistic performance, easy to learn Go web framework. Iris provides a beautifully expressive and easy to use foundation for your next website, API, or distributed app. Low-level handlers compatible with `net/http` and high-level fastest MVC implementation and handlers dependency injection. Easy to learn for new gophers and advanced features for experienced, it goes as far as you dive into it! Source code and other details for the project are available at GitHub: 12.1.8 The only requirement is the Go Programming Language, at least version 1.13. Wiki: Examples: Middleware: Home Page:
Service Provider Interface used for dependency injection IOC. Service Descriptor used for dependency injection IOC. Service Provider used for dependency injection IOC. Service Scope used for dependency injection IOC. Service Type Enum used for dependency injection IOC.
The modules package implements binders for dependency injection of tagged struct fields.
Package inject provides a reflect based injector. A large application built with dependency injection in mind will typically involve the boring work of setting up the object graph. This library attempts to take care of this boring work by creating and connecting the various objects. Its use involves you seeding the object graph with some (possibly incomplete) objects, where the underlying types have been tagged for injection. Given this, the library will populate the objects creating new ones as necessary. It uses singletons by default, supports optional private instances as well as named instances. It works using Go's reflection package and is inherently limited in what it can do as opposed to a code-gen system with respect to private fields. The usage pattern for the library involves struct tags. It requires the tag format used by the various standard libraries, like json, xml etc. It involves tags in one of the three forms below: The first no value syntax is for the common case of a singleton dependency of the associated type. The second triggers creation of a private instance for the associated type. Finally the last form is asking for a named dependency called "dev logger".
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package container provides 'dependency injection' functionality. A large part of this is done through the 'dependency injection container', which is reified through the 'container.Container' interface, and created by calling the 'container.New()' func. As in: You do 3 things with a 'dependency injection container'. (Although it is possible that in practice you might only do 2 of these 3 things. But if you end up doing all 3 of these things, that's OK too.) #1: You register things with the container, giving the thing you registed a (string) name when you register it. For example: Also, for example: #2: You manually get things out of the container. (Doing this is a bit involved, but #3 provides a better alternative to this method.) For example: Also, for example: #3: The container can inject dependencies into something. For example:
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package fx is a framework that makes it easy to build applications out of reusable, composable modules. Fx applications use dependency injection to eliminate globals without the tedium of manually wiring together function calls. Unlike other approaches to dependency injection, Fx works with plain Go functions: you don't need to use struct tags or embed special types, so Fx automatically works well with most Go packages. Basic usage is explained in the package-level example below. If you're new to Fx, start there! Advanced features, including named instances, optional parameters, and value groups, are explained under the In and Out types. To test functions that use the Lifecycle type or to write end-to-end tests of your Fx application, use the helper functions and types provided by the go.uber.org/fx/fxtest package.
Package controllerruntime provides tools to construct Kubernetes-style controllers that manipulate both Kubernetes CRDs and aggregated/built-in Kubernetes APIs. It defines easy helpers for the common use cases when building CRDs, built on top of customizable layers of abstraction. Common cases should be easy, and uncommon cases should be possible. In general, controller-runtime tries to guide users towards Kubernetes controller best-practices. The main entrypoint for controller-runtime is this root package, which contains all of the common types needed to get started building controllers: The examples in this package walk through a basic controller setup. The kubebuilder book (https://book.kubebuilder.io) has some more in-depth walkthroughs. controller-runtime favors structs with sane defaults over constructors, so it's fairly common to see structs being used directly in controller-runtime. A brief-ish walkthrough of the layout of this library can be found below. Each package contains more information about how to use it. Frequently asked questions about using controller-runtime and designing controllers can be found at https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ.md. Every controller and webhook is ultimately run by a Manager (pkg/manager). A manager is responsible for running controllers and webhooks, and setting up common dependencies (pkg/runtime/inject), like shared caches and clients, as well as managing leader election (pkg/leaderelection). Managers are generally configured to gracefully shut down controllers on pod termination by wiring up a signal handler (pkg/manager/signals). Controllers (pkg/controller) use events (pkg/events) to eventually trigger reconcile requests. They may be constructed manually, but are often constructed with a Builder (pkg/builder), which eases the wiring of event sources (pkg/source), like Kubernetes API object changes, to event handlers (pkg/handler), like "enqueue a reconcile request for the object owner". Predicates (pkg/predicate) can be used to filter which events actually trigger reconciles. There are pre-written utilities for the common cases, and interfaces and helpers for advanced cases. Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A Reconciler implements a function which takes a reconcile Request containing the name and namespace of the object to reconcile, reconciles the object, and returns a Response or an error indicating whether to requeue for a second round of processing. Reconcilers use Clients (pkg/client) to access API objects. The default client provided by the manager reads from a local shared cache (pkg/cache) and writes directly to the API server, but clients can be constructed that only talk to the API server, without a cache. The Cache will auto-populate with watched objects, as well as when other structured objects are requested. The default split client does not promise to invalidate the cache during writes (nor does it promise sequential create/get coherence), and code should not assume a get immediately following a create/update will return the updated resource. Caches may also have indexes, which can be created via a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to quickly and easily look up all objects with certain fields set. Reconcilers may retrieve event recorders (pkg/recorder) to emit events using the manager. Clients, Caches, and many other things in Kubernetes use Schemes (pkg/scheme) to associate Go types to Kubernetes API Kinds (Group-Version-Kinds, to be specific). Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but are often constructed using a builder (pkg/webhook/admission/builder). They are run via a server (pkg/webhook) which is managed by a Manager. Logging (pkg/log) in controller-runtime is done via structured logs, using a log set of interfaces called logr (https://godoc.org/github.com/go-logr/logr). While controller-runtime provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), you can provide any implementation of logr as the base logger for controller-runtime. Metrics (pkg/metrics) provided by controller-runtime are registered into a controller-runtime-specific Prometheus metrics registry. The manager can serve these by an HTTP endpoint, and additional metrics may be registered to this Registry as normal. You can easily build integration and unit tests for your controllers and webhooks using the test Environment (pkg/envtest). This will automatically stand up a copy of etcd and kube-apiserver, and provide the correct options to connect to the API server. It's designed to work well with the Ginkgo testing framework, but should work with any testing setup. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support This example creates a simple application Controller that is configured for ReplicaSets and Pods. This application controller will be running leader election with the provided configuration in the manager options. If leader election configuration is not provided, controller runs leader election with default values. Default values taken from: https://github.com/kubernetes/apiserver/blob/master/pkg/apis/config/v1alpha1/defaults.go * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package dig provides an opinionated way of resolving object dependencies. STABLE. No breaking changes will be made in this major version. Dig exposes type Container as an object capable of resolving a directed acyclic dependency graph. Use the New function to create one. Constructors for different types are added to the container by using the Provide method. A constructor can declare a dependency on another type by simply adding it as a function parameter. Dependencies for a type can be added to the graph both, before and after the type was added. Multiple constructors can rely on the same type. The container creates a singleton for each retained type, instantiating it at most once when requested directly or as a dependency of another type. Constructors can declare any number of dependencies as parameters and optionally, return errors. Constructors can also return multiple results to add multiple types to the container. Constructors that accept a variadic number of arguments are treated as if they don't have those arguments. That is, Is treated the same as, The constructor will be called with all other dependencies and no variadic arguments. Types added to to the container may be consumed by using the Invoke method. Invoke accepts any function that accepts one or more parameters and optionally, returns an error. Dig calls the function with the requested type, instantiating only those types that were requested by the function. The call fails if any type or its dependencies (both direct and transitive) were not available in the container. Any error returned by the invoked function is propagated back to the caller. Constructors declare their dependencies as function parameters. This can very quickly become unreadable if the constructor has a lot of dependencies. A pattern employed to improve readability in a situation like this is to create a struct that lists all the parameters of the function as fields and changing the function to accept that struct instead. This is referred to as a parameter object. Dig has first class support for parameter objects: any struct embedding inject.In gets treated as a parameter object. The following is equivalent to the constructor above. Handlers can receive any combination of parameter objects and parameters. Result objects are the flip side of parameter objects. These are structs that represent multiple outputs from a single function as fields in the struct. Structs embedding inject.Out get treated as result objects. The above is equivalent to, Constructors often don't have a hard dependency on some types and are able to operate in a degraded state when that dependency is missing. Dig supports declaring dependencies as optional by adding an `optional:"true"` tag to fields of a inject.In struct. Fields in a inject.In structs that have the `optional:"true"` tag are treated as optional by Dig. If an optional field is not available in the container, the constructor will receive a zero value for the field. Constructors that declare dependencies as optional MUST handle the case of those dependencies being absent. The optional tag also allows adding new dependencies without breaking existing consumers of the constructor. Some use cases call for multiple values of the same type. Dig allows adding multiple values of the same type to the container with the use of Named Values. Named Values can be produced by passing the inject.Name option when a constructor is provided. All values produced by that constructor will have the given name. Given the following constructors, You can provideWithConstructor *sql.DB into a Container under different names by passing the inject.Name option. Alternatively, you can produce a inject.Out struct and tag its fields with `name:".."` to have the corresponding value added to the graph under the specified name. Regardless of how a Named Value was produced, it can be consumed by another constructor by accepting a inject.In struct which has exported fields with the same name AND type that you provided. The name tag may be combined with the optional tag to declare the dependency optional. Added in Dig 1.2. Dig provides value groups to allow producing and consuming many values of the same type. Value groups allow constructors to send values to a named, unordered collection in the container. Other constructors can request all values in this collection as a slice. Constructors can send values into value groups by returning a inject.Out struct tagged with `group:".."`. Any number of constructors may provideWithConstructor values to this named collection. Other constructors can request all values for this collection by requesting a slice tagged with `group:".."`. This will execute all constructors that provideWithConstructor a value to that group in an unspecified order. Note that values in a value group are unordered. Dig makes no guarantees about the order in which these values will be produced.
Package echo provides dependency injection definitions.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Service Provider Interface used for dependency injection IOC. Service Descriptor used for dependency injection IOC. Service Provider used for dependency injection IOC. Service Scope used for dependency injection IOC. Service Type Enum used for dependency injection IOC.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
https://github.com/google/guice/wiki/Motivation This project is in no way affiliated with the Guice project, but I recommend reading their docs to better understand the concepts. A Module is analogous to Guice's AbstractModule, used for setting up your dependencies. This allows you to bind structs, struct pointers, interfaces, and primitives to singletons, constructors, with or without tags. An interface can have a binding to another type, or to a singleton or constructor. An interface can also be bound to a singleton or constructor. A struct, struct pointer, or primitive must have a direct binding to a singleton or constructor. All errors from binding will be returned as one error when calling inject.NewInjector(...). An Injector is analogous to Guice's Injector, providing your dependencies. Given the binding: We are able to get a value for SayHello. See the Injector interface for other methods. A constructor is a function that takes injected values as parameters, and returns a value and an error. We can set up a constructor to take zero values, or values that require a binding in some module passed to NewInjector(). A singleton constructor will be called exactly once for the entire application. The simplest way of binding an interface to a constructor function is to use the `BindConstructor` or `BindSingletonConstructor` methods. They automatically determine the interface type that is bound to the constructor from the constructor's return value. The following examples are equivalent to the more verbose ones above: A singleton bound through a constructor function can be marked as _eager_, in which case it will be constructed automatically by the injector during the injector creation process. The advantage is that every time the singleton is injected it is already available, whereas a normal (_lazy_) singleton has to be created before injecting it the first time. Eager singletons also reveal initialization problems sooner - at the time of injector creation rather than the first time the singleton is used. In addition, an eager singleton can be combined with an additional arbitrary function call, that will also be performed by the injector on construction. This can be used, for example, to initialize a "traditional" singleton implemented with a global variable: Functions can be called from an injector using the Call function. These functions have the same parameter requirements as constructors, but can have any return types. See the methods on Module and Constructor for more details. A tag allows named multiple bindings of one type. As an example, let's consider if we want to have multiple ways to say hello. Structs can also be populated using the tag "inject". Constructors can be tagged using structs, either named or anonymous. A constructor can mix tagged values with untagged values in the input struct. The CallTagged function works similarly to Call, except can take parameters like a tagged constructor. Both Module and Injector implement fmt.Stringer for inspection, however this may be added to in the future to allow semantic inspection of bindings. For testing, production modules may be overridden with test bindings as follows:
Package fx is a framework that makes it easy to build applications out of reusable, composable modules. Fx applications use dependency injection to eliminate globals without the tedium of manually wiring together function calls. Unlike other approaches to dependency injection, Fx works with plain Go functions: you don't need to use struct tags or embed special types, so Fx automatically works well with most Go packages. Basic usage is explained in the package-level example below. If you're new to Fx, start there! Advanced features, including named instances, optional parameters, and value groups, are explained under the In and Out types. To test functions that use the Lifecycle type or to write end-to-end tests of your Fx application, use the helper functions and types provided by the go.uber.org/fx/fxtest package.
Package hiboot is a web/cli app application framework Hiboot is a cloud native web and cli application framework written in Go. Hiboot integrates the popular libraries but make them simpler, easier to use. It borrowed some of the Spring features like dependency injection, aspect oriented programming, and auto configuration. You can integrate any other libraries easily by auto configuration with dependency injection support. hiboot-data is the typical project that implement customized hiboot starters. see https://godoc.org/hidevops.io/hiboot-data Overview One of the most significant feature of Hiboot is Dependency Injection. Hiboot implements JSR-330 standard. Let's say that we have two implementations of AuthenticationService, below will explain how does Hiboot work. In Hiboot the injection into fields is triggered by `inject:""` struct tag. when inject tag is present on a field, Hiboot tries to resolve the object to inject by the type of the field. If several implementations of the same service interface are available, you have to disambiguate which implementation you want to be injected. This can be done by naming the field to specific implementation. Although Field Injection is pretty convenient, but the Constructor Injection is the first-class citizen, we usually advise people to use constructor injection as it has below advantages, It's testable, easy to implement unit test. Syntax validation, with syntax validation on most of the IDEs to avoid typo. No need to use a dedicated mechanism to ensure required properties are set. type userController struct { web.Controller basicAuthenticationService AuthenticationService } // Hiboot will inject the implementation of AuthenticationService func newUserController(basicAuthenticationService AuthenticationService) { return &userController{ basicAuthenticationService: basicAuthenticationService, } } func init() { app.Register(newUserController) } Features This section will show you how to create and run a simplest hiboot application. Let’s get started! Get the source code Source Code This is a simple hello world example