Comments (5)
Hi again, @fionera!
Your code might look like this:
package main
import (
"fmt"
"log"
"github.com/goava/di"
)
type Configuration struct {
Enabled bool
}
func NewConfiguration() *Configuration {
return &Configuration{Enabled: true}
}
func main() {
var conf *Configuration
container, err := di.New(
di.Provide(NewConfiguration),
di.Resolve(&conf),
)
if err != nil {
log.Fatal(err)
}
if conf.Enabled {
if err := container.Invoke(func() { fmt.Println("Hello World") }); err != nil {
log.Fatal(err)
}
}
}
If we are talking about providing depending on the availability of a certain type:
package main
import (
"log"
"net/http"
"github.com/goava/di"
)
func NewHTTPServer(mux http.Handler) *http.Server {
return &http.Server{
Handler: mux,
}
}
func main() {
container, err := di.New(
di.Provide(http.NewServeMux, di.As(new(http.Handler))), // if comment on this, the server will not be provided
di.WithCompile(), // eject compilation stage
)
if err != nil {
log.Fatal(err)
}
var handler http.Handler
if container.Has(&handler) { // checking for a handler
if err := container.Provide(NewHTTPServer); err != nil { // provide if handler exists
log.Fatal(err)
}
}
if err := container.Compile(); err != nil {
log.Fatal(err)
}
var server *http.Server
if err := container.Resolve(&server); err != nil {
log.Fatal(err) // server not provided
} else {
log.Println("Server resolved")
}
}
But if you need to provide type depending on the already initialized instance:
type Configuration struct {
Enabled bool
}
di.New(
di.Provide(func () *Configuration {
return &Configuration{ true }
}),
di.Provide(func(configuration *Configuration) di.Option {
if configuration.Enabled {
return di.Provide(NewMyType) // Provide instead Invoke
}
return nil
})
)
In this example configuration already built and Provide()
breaks the order of building the dependency graph.
Modifying an already compiled graph is a bad way and intentionally impossible. This can cause unnecessary side effects.
I want to keep container workaround strictly consistent:
- building: available
Provide()
andHas()
methods; - compilation: parses dependencies params, build dependency graph and check that it is correct;
- interaction: available
Invoke()
,Resolve()
andHas()
method.
If you describe your real problem in more detail, we will find a solution.
from di.
This feature is easier to understand when used with #4.
I have a interface I implement with different config backends. Depending on the Environment, one of these will get added to the Container and Provide it. All Modules in this Application are Providing their own Configuration struct and as construtor field have the Config interface.
This way all Configurations structs are getting filled by the correct Config backend. I also have Provides that depend on this Configuration Struct and returns more Options, like Provide and Invokes, like how they are in fx, to the Container/App.
This way I can enable parts of the App by changing the Config and only ever interact with the parsed config struct without being verbose or having any connection between the config system and the fact that smth is enabled.
from di.
@fionera Can you provide a library from another language with similar functionality so that I can research it? I'm sure there are a lot of pitfalls here.
from di.
Ive implemented it into fx myself and didnt found anything that could be a pitfall. You basically split up the handling of Provide entries in the Compile process. fionera/fx@c2d9ca7
from di.
If you want I can port this to di and make a PR
from di.
Related Issues (20)
- Unable to make interfaces group by using the same funtion interface implenentations HOT 11
- container.Resolve() doesn't create signleton when dependency requested via intermidiate constructor HOT 2
- No documentation for the *Container.Has() method HOT 1
- Using `di.WithName()` breaks when having one entry without a `di.Name()` HOT 7
- Parameter structs need an empty di tag on an entry else it gets ignored HOT 1
- Allow decorating of services in the container HOT 8
- concurrent map read and map write HOT 6
- Duplicate instance with di.As HOT 2
- Singleton HOT 1
- Handle embed unnamed dependency HOT 1
- Improve tracing HOT 2
- Support the ability to chain containers (to form scopes) HOT 3
- Change how Injected structs are tagged HOT 4
- Why should I pass a pointer to the type? HOT 2
- Possibility to disable singleton behavior. HOT 5
- Important: Upcoming Transfer of This Repository on June 5th
- Issue after package name migration HOT 4
- Provide values via custom string types HOT 2
- Overriding a value from a parent di container
- Factory function returning other di.Provide HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from di.