wire icon indicating copy to clipboard operation
wire copied to clipboard

Provide a way to add to wired providers - init skipped fields, or add cleanup/error

Open scr-oath opened this issue 4 years ago • 0 comments

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

Sometimes there are fields that may need construction but not injection - typical examples are making a map for caching, or channel for whatever.

The only trick I've found so far is to make a secondary type, such as


struct InjectedBase {
  Config *config.Config
  HttpClient *http.Client
}

struct Injected {
  InjectedBase

  tokenForHost map[string]string `wire:"-"`
}

func NewInjectedFromBase(base *InjectedBase) (*Injected, func()) {
  ret := &Injected{
    InjectedBase: *base,
    tokenForHost: make(map[string]string),
  }
  return ret, ret.Close
}

var DefaultSet = wire.NewSet(
  wire.Struct(new(InjectedBase), "*"),
  NewInjectedFromBase,
)
var buildSet = DefaultSet

func NewInjected() *Injected {
  panic(wire.Build(buildSet))
}

Describe the solution you'd like

It would be great if a provider modifier could be somehow specified… Something like

func WrapInjected(i *Injected) (*Injected, func()) {
  i.tokenForHost = make(map[string]string)
  return i, i.Close
}

var DefaultSet = wire.NewSet(
  wire.Struct(new(Injected), "*"),
  WrapInjected,
)

or maybe pass the wrapping to the wire.Struct call…

var DefaultSet = wire.NewSet(
  wire.Struct(new(Injected), WrapInjected, "*"),
)

Describe alternatives you've considered

We could always just do the two-class solution with "base" and "real" but it creates extra tedium to something that wire could make really pleasing.

Additional context

The two cases that could be solved with this wrapping style would be for:

  1. construction
  2. destruction ("cleanup")

It would be really great to be able to have the cleanup as part of wire so that in the above example, if there's a "Close" method, each struct that has the Injected thing doesn't also need to (manually) add a Close method that closes the injected thing - but only the place where the injection starts (main(), e.g.) would have to defer cleanup() and that would do all the great wired composition of cleanups of all the things in the right reverse-order sequence.

scr-oath avatar Jun 29 '21 01:06 scr-oath