wire icon indicating copy to clipboard operation
wire copied to clipboard

[Feature] Support conditional bindings

Open phroggyy opened this issue 6 years ago • 2 comments

Is your feature request related to a problem? Please describe.

When building applications, we might want to support different database drivers, e.g using Go CDK and using the in-memory docstore for development, and mongo or firestore for production. For the scenarios, it would be useful if there was a way to conditionally generate code.

This does reduce flexibility, but eases development, especially when you are wiring up something that is unlikely to change often (e.g the database driver is unlikely to change without a re-compilation anyway).

Describe the solution you'd like

When running wire, the wire generator will execute conditionals at generation time (e.g if you have a switch on an env variable, it would do a check based on the env variable set at the time wire was run).

Describe alternatives you've considered

I have looked at the proposed solution of #205, but this still causes problems since we then are back at needing to effectively build out the whole dependency ourselves.

Additional context

Example of current conditional implementation

wire.go

wire.Build(
	conversations.NewManager,
	datastore.ProvideCollection,
	wire.Value(datastore.CollectionName("conversations")),
	datastore.ProvideContext,
)

return &conversations.ConversationManager{}, nil

datastore/store.go

func ProvideCollection(ctx context.Context, name CollectionName) (*docstore.Collection, error) {
	switch os.Getenv("DB_DRIVER") {
	case "mongo":
		return NewMongoCollection(ctx, ProvideHostName(), ProvideDatabaseName(), name)
	case "memory":
		return NewInMemoryCollection()
	}
	
	return nil, errors.New("tried to initialize invalid driver")
}

Desired configuration:

wire.go

switch os.Getenv("DB_DRIVER") {
case "mongo":
	wire.Build(
		conversations.NewManager,
		datastore.MongoProviderSet,
		wire.Value(datastore.CollectionName("conversations")),
		datastore.ProvideContext,
	)
	return &conversations.ConversationManager{}, nil
case "memory":
	wire.Build(conversations.NewManager, datastore.NewInMemoryCollection, datastore.ProvideContext)

	return &conversations.ConversationManager{}, nil
}

return nil, errors.New("tried to initialize invalid driver")

phroggyy avatar Oct 04 '19 13:10 phroggyy

Thanks for the suggestion @phroggyy I'll keep this issue open as a feature request, but we consider wire feature-complete at this point and will not be adding features. We want it to stabilize and will fix bugs, but there's value in a simple tool that doesn't have too many capabilities and just does the job.

eliben avatar Oct 04 '19 13:10 eliben

If you want conditional behavior at compile time, consider using Go's build tags: https://golang.org/pkg/go/build/. I.e., you could use wire to produce both configurations, and only include one of them in your build.

vangent avatar Oct 04 '19 15:10 vangent