Fill takes a struct and resolves the fields with the tag `container:"inject"`
(structure interface{})
| 251 | |
| 252 | // Fill takes a struct and resolves the fields with the tag `container:"inject"` |
| 253 | func (c Container) Fill(structure interface{}) error { |
| 254 | receiverType := reflect.TypeOf(structure) |
| 255 | if receiverType == nil { |
| 256 | return errors.New("container: invalid structure") |
| 257 | } |
| 258 | |
| 259 | if receiverType.Kind() == reflect.Ptr { |
| 260 | elem := receiverType.Elem() |
| 261 | if elem.Kind() == reflect.Struct { |
| 262 | s := reflect.ValueOf(structure).Elem() |
| 263 | |
| 264 | for i := 0; i < s.NumField(); i++ { |
| 265 | f := s.Field(i) |
| 266 | |
| 267 | if t, exist := s.Type().Field(i).Tag.Lookup("container"); exist { |
| 268 | var name string |
| 269 | |
| 270 | if t == "type" { |
| 271 | name = "" |
| 272 | } else if t == "name" { |
| 273 | name = s.Type().Field(i).Name |
| 274 | } else { |
| 275 | return fmt.Errorf("container: %v has an invalid struct tag", s.Type().Field(i).Name) |
| 276 | } |
| 277 | |
| 278 | if concrete, exist := c[f.Type()][name]; exist { |
| 279 | instance, err := concrete.make(c) |
| 280 | if err != nil { |
| 281 | return err |
| 282 | } |
| 283 | |
| 284 | ptr := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem() |
| 285 | ptr.Set(reflect.ValueOf(instance)) |
| 286 | |
| 287 | continue |
| 288 | } |
| 289 | |
| 290 | return fmt.Errorf("container: cannot make %v field", s.Type().Field(i).Name) |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | return nil |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | return errors.New("container: invalid structure") |
| 299 | } |