make<T> method

T make<T>([
  1. Type? type
])

Instantiates an instance of T.

In contexts where a static generic type cannot be used, use the type argument, instead of T.

Implementation

T make<T>([Type? type]) {
  var t2 = T;
  if (type != null) {
    t2 = type;
  }

  Container? search = this;

  while (search != null) {
    if (search._singletons.containsKey(t2)) {
      // Find a singleton, if any.
      return search._singletons[t2] as T;
    } else if (search._factories.containsKey(t2)) {
      // Find a factory, if any.
      return search._factories[t2]!(this) as T;
    } else {
      search = search._parent;
    }
  }

  var reflectedType = reflector.reflectType(t2);
  var positional = [];
  var named = <String, dynamic>{};

  if (reflectedType is ReflectedClass) {
    bool isDefault(String name) {
      return name.isEmpty || name == reflectedType.name;
    }

    var constructor = reflectedType.constructors.firstWhere(
        (c) => isDefault(c.name),
        orElse: (() => throw ReflectionException(
            '${reflectedType.name} has no default constructor, and therefore cannot be instantiated.')));

    for (var param in constructor.parameters) {
      var value = make(param.type.reflectedType);

      if (param.isNamed) {
        named[param.name] = value;
      } else {
        positional.add(value);
      }
    }

    return reflectedType.newInstance(
        isDefault(constructor.name) ? '' : constructor.name,
        positional,
        named, []).reflectee as T;
  } else {
    throw ReflectionException(
        '$t2 is not a class, and therefore cannot be instantiated.');
  }
}