Dependency Injection by annotations for Golang https://github.com/lokstory/digo
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.
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
Package echo provides dependency injection definitions.
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 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 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 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 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 inject provides a dependency injection library that uses constructor functions to define dependency relationships. Source can be found at https://github.com/karlkfi/inject Author: Karl Isenberg
Package scaffolder is a dependency injection framework dedicated into abstracting the redundant boilerplate needed to build any Golang application and letting you build what you want to build without having to rewrite yet another /health endpoint.
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 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 sector provides a simple way to do dependency injection in Go. Tag `inject:"+"` means inject this field and tag `inject:"*"` means inject this field and all it's injectable members.
Package npoint is a general purpose lightweight non-opinionated web server framework that provides a concise way to handle errors and inject dependencies into http endpoint handlers. Composite endpoints: endpoints are assembled from a collection of handlers. Before/after actions: the middleware handler type wraps the rest of the handler chain so that it can both inject items that are used downstream and process return values. Dependency injection: injectors, static injectors, and fallible injectors can all be used to provide data and code to downstream handlers. Downstream handlers request what they need by including appropriate types in their argument lists. Injectors are invoked only if their outputs are consumed. Code juxtaposition: when using pre-registered services, endpoint binding can be registered next to the code that implements the endpoint even if the endpoints are implemented in multiple files and/or packages. Delayed initialization: initializers for pre-registered services are only executed when the service is started and bound to an http server. This allow code to define such endpoints to depend on resources that may not be present unless the service is started. Reduced refactoring cost: handlers and endpoints declare their inputs and outputs in the argument lists and return lists. Handlers only need to know about their own inputs and outputs. The endpoint framework carries the data to where it is needed. It does so with a minimum of copies and without recursive searches (see context.Context). Type checking is done at service start time (or endpoint binding time when binding to services that are already running). Lower overhead indirect passing: when using context.Context to pass values indirectly, the Go type system cannot be used to verify types at compile time or startup time. Endpoint verifies types at startup time allowing code that receives indirectly-passed data simpler. As much as possible, work is done at initialization time rather than endpoint invocation time. To use the npoint package, create services first. After that the endpoints can be registered to the service and the service can be started. A simpler way to use endpoint is to use the CreateEndpoint function. It converts a list of handlers into an http.HandlerFunc. This bypasses service creation and endpoint registration. See https://github.com/muir/npoint/blob/master/README.md for an example. Service is a collection of endpoints that can be started together and may share a handler collection. Handler is a function that is used to help define an endpoint. Handler collection is a group of handlers. Downstream handlers are handlers that are to the right of the current handler in the list of handlers. They will be invoked after the current handler. Upstream handlers are handlers that are to the left of the current handler in the list of handlers. They will have already been invoked by the time the current handler is invoked. A service allows a group of related endpoints to be started together. Each service may have a set of common handlers that are shared among all the endpoints registered with that service. Services come in four flavors: started or pre-registered; with Mux or with without. Pre-registered services are not initialized until they are Start()ed. This allows them to depend upon resources that may not may not be available without causing a startup panic unless they're started without their required resources. It also allows endpoints to be registered in init() functions next to the definition of the endpoint. The handlers are defined using the nject framework: See https://github.com/muir/nject/blob/master/README.md A list of handlers will be invoked from left-to-right. The first handler in the list is invoked first and the last one (the endpoint) is invoked last. The handlers do not directly call each other -- rather the framework manages the invocations. Data provided by one handler can be used by any handler to its right and then as the handlers return, the data returned can be used by any handler to its left. The data provided and required is identified by its type. Since Go makes it easy to make aliases of types, it is easy to make types distinct. When there is not an exact match of types, the framework will use the closest (in distance) value that can convert to the required type. Each handler function is distinguished by its position in the handler list and by its primary signature: its arguments and return values. In Go, types may be named or unnamed. Unnamed function types are part of primary signature. Named function types are not part of the primary signature. These are the types that are recognized as valid handlers: Static Injectors, Injectors, Endpoints, and Middleware. Injectors are only invoked if their output is consumed or they have no output. Middleware handlers are (currently) always invoked. There are three kinds of injectors: static injectors, injectors, and fallible injectors. Injectors and static injectors have the following type signature: None of the input or output parameters may be un-named functions. That describes nearly every function in Go. Handlers that match a more specific type signature are that type, rather than being an injector or static injector. Injectors whose output values are not used by a downstream handler are dropped from the handler chain. They are not invoked. Injectors that have no output values are a special case and they are always retained in the handler chain. Static injectors are called exactly once per endpoint. They are called when the endpoint is started or when the endpoint is registered -- whichever comes last. Values returned by static injectors will be shared by all invocations of the endpoint. Injectors are called once per endpoint invocation (or more if they are downstream from a middleware handler that calls inner() more than once). Injectors a distingued from static injectors by either their position in the handler list or by the parameters that they take. If they take http.ResponseWriter or *http.Request, then they're not static. Anything that is downstream of a non-static injector or middleware handler is also not static. Fallible injectors are injectors whose first return values is of type nject.TerminalError: If a non-nil value is returned as the nject.TerminalError from a fallible injector, none of the downstream handlers will be called. The handler chain returns from that point with the nject.TerminalError as a return value. Since all return values must be consumed by a middleware handler, fallible injectors must come downstream from a middleware handler that takes nject.TerminalError as a returned value. If a fallible injector returns nil for the nject.TerminalError, the other output values are made available for downstream handlers to consume. The other output values are not considered return values and are not available to be consumed by upstream middleware handlers. Some examples: Middleware handlers wrap the handlers downstream in a inner() function that they may call. The type signature of a middleware handler is a function that receives an function as its first parameter. That function must be of an anonymous type: For example: When this middleware function runs, it is responsible for invoking the rest of the handler chain. It does this by calling inner(). The parameters to inner are available as inputs to downstream handlers. The value(s) returned by inner come from the return values of downstream middleware handlers and the endpoint handler. Middleware handlers can call inner() zero or more times. The values returned by middleware handlers must be consumed by another upstream middlware handler. Endpoint handlers are simply the last handler in the handler chain. They look like regular Go functions. Their input parameters come from other handlers. Their return values (if any) must be consumed by an upstream middleware handler. Endpoint will panic during endpoint registration if the provided handlers do not constitute a valid chain. For example, if a some handler requires a FooType but there is no upstream handler that provides a FooType then the handler list is invalid and endpoint will panic. Endpoint should not panic after initialization.
The modules package implements binders for dependency injection of tagged struct fields.
Package gimple is a Dependency Injection Container developed in Golang with features highly inspired on Pimple, a micro dependency injection container for PHP. Some of it's features is: - Define services; - Define factories; - Define parameters easily; - Allow services to depend directly on interfaces, and not on concrete struct; - Defining services/parameters/factories from another files - because you should be able to split your configuration easily; - Simple API; - Allows extending services easily; - Allow to get the raw service creator easily; - Pure Go, no C code envolved; - Fully tested on each commit; - I already said that it have a really Simple API? :)
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 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 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
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:
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 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 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 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 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 inject provides utilities for mapping and injecting dependencies in various ways.
Package inject provides utilities for mapping and injecting dependencies in various ways.
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 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 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 inject provides utilities for mapping and injecting dependencies in various ways.
Package graph may be useful for developers tasked with storage, compute and network management for cloud microservices. The library provides types and functions that enable a modular, extensible programming model. Resource interface is a declarative abstraction of a storage, compute or network service. Resources may have a Dependency order of creation and deletion. Idiomatic resources may have a single backing structure for fulfilling the interface. The library utilizes this backing structure to locate and inject public properties of a resource during execution. The library manages a collection of related resources at a given time. The Sync() function provides a method for managing a collection of resources: The library tries to execute multiple resources concurrently. There is a handy ErrorMapper interface that allows developers to query resource specific errors. Use the following code snippet: This example shows basic resource synchronization. There are three different resources that we need to build: an AWS Kinesis stream, an Aws Dynamo DB table, and finally a Kubernetes deployment of a micro- service that depends on both of the other resources being created properly.
package goject 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 Container. This library attempts to take care of this boring work by creating and connecting the various objects. Its use involves you seeding the object Container 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 di is an dependency injection container implements. Source code and other details for the project are available at GitHub:
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 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