# Interface PolymorphicDomainObjectContainer<T>

Type Parameters:
  `T` - the (base) type of objects in the container

All Superinterfaces:
  `Collection<T>, Configurable<NamedDomainObjectContainer<T>>, DomainObjectCollection<T>, DomainObjectSet<T>, Iterable<T>, NamedDomainObjectCollection<T>, NamedDomainObjectContainer<T>, NamedDomainObjectSet<T>, Set<T>`

All Known Subinterfaces:
  `AuthenticationContainer, ExtensiblePolymorphicDomainObjectContainer<T>, NativeToolChainRegistry, PlatformContainer, PublicationContainer, Repositories, SoftwareComponentContainer, TaskContainer`

public interface PolymorphicDomainObjectContainer<T> extends NamedDomainObjectContainer<T>
A `NamedDomainObjectContainer` that allows you to create objects with different types.

Since:
  1.5

- ## Method Summary

  Modifier and Type
  Method
  Description
  `<U extends T>
  NamedDomainObjectContainer<U>`
  `containerWithType(Class<U> type)`
  Creates a regular container that wraps the polymorphic container presenting all elements of a specified type.
  `<U extends T>
  U`
  `create(String name, Class<U> type)`
  Creates a domain object with the specified name and type, and adds it to the container.
  `<U extends T>
  U`
  `create(String name, Class<U> type, Action<? super U> configuration)`
  Creates a domain object with the specified name and type, adds it to the container, and configures it with the specified action.
  `<U extends T>
  U`
  `maybeCreate(String name, Class<U> type)`
  Looks for an item with the given name and type, creating and adding it to this container if it does not exist.
  `<U extends T>
  NamedDomainObjectProvider<U>`
  `register(String name, Class<U> type)`
  Defines a new object, which will be created when it is required.
  `<U extends T>
  NamedDomainObjectProvider<U>`
  `register(String name, Class<U> type, Action<? super U> configurationAction)`
  Defines a new object, which will be created and configured when it is required.

  ### Methods inherited from interface Collection

  `parallelStream, removeIf, stream, toArray`

  ### Methods inherited from interface DomainObjectCollection

  `addAllLater, addLater, all, all, configureEach, disallowChanges, getElements, whenObjectAdded, whenObjectAdded, whenObjectRemoved, whenObjectRemoved, withType, withType`

  ### Methods inherited from interface Iterable

  `forEach`

  ### Methods inherited from interface NamedDomainObjectCollection

  `add, addAll, addRule, addRule, addRule, findByName, getAsMap, getAt, getByName, getByName, getByName, getCollectionSchema, getNamer, getNames, getRules, named, named, named, named`

  ### Methods inherited from interface NamedDomainObjectContainer

  `configure, create, create, create, maybeCreate, register, register`

  ### Methods inherited from interface NamedDomainObjectSet

  `findAll, matching, matching, named, withType`

  ### Methods inherited from interface Set

  `add, addAll, clear, contains, containsAll, equals, hashCode, isEmpty, iterator, remove, removeAll, retainAll, size, spliterator, toArray, toArray`

- ## Method Details

  - ### create

    <U extends T> U create(String name, Class<U> type) throws InvalidUserDataException
    Creates a domain object with the specified name and type, and adds it to the container.

    This operation is eager, the element is realized before being returned.

    Type Parameters:
      `U` - the type of the domain object to be created
    Parameters:
      `name` - the name of the domain object to be created
      `type` - the type of the domain object to be created
    Returns:
      the created domain object
    Throws:
      `InvalidUserDataException` - if a domain object with the specified name already exists or the container does not support creating a domain object with the specified type
    Since:
      1.5

  - ### maybeCreate

    <U extends T> U maybeCreate(String name, Class<U> type) throws InvalidUserDataException
    Looks for an item with the given name and type, creating and adding it to this container if it does not exist.

    This operation is eager, the element is realized before being returned.

    Type Parameters:
      `U` - the type of the domain object to be created
    Parameters:
      `name` - the name of the domain object to be created
      `type` - the type of the domain object to be created
    Returns:
      the found or created domain object, never `null`.
    Throws:
      `InvalidUserDataException` - if the container does not support creating a domain object with the specified type
      `ClassCastException` - if a domain object with the specified name exists with a different type
    Since:
      1.11

  - ### create

    <U extends T> U create(String name, Class<U> type, Action<? super U> configuration) throws InvalidUserDataException
    Creates a domain object with the specified name and type, adds it to the container, and configures it with the specified action.

    This operation is eager, the element is realized before being returned.

    Type Parameters:
      `U` - the type of the domain object to be created
    Parameters:
      `name` - the name of the domain object to be created
      `type` - the type of the domain object to be created
      `configuration` - an action for configuring the domain object
    Returns:
      the created domain object
    Throws:
      `InvalidUserDataException` - if a domain object with the specified name already exists or the container does not support creating a domain object with the specified type
    Since:
      1.5

  - ### containerWithType

    <U extends T> NamedDomainObjectContainer<U> containerWithType(Class<U> type)
    Creates a regular container that wraps the polymorphic container presenting all elements of a specified type.

    This method is an intermediate operation. It does not change the realized/unrealized state of the elements in the collection.

    Type Parameters:
      `U` - the type of the container elements
    Parameters:
      `type` - the type of the container elements
    Returns:
      a `NamedDomainObjectContainer` providing access to elements of type U.
    Since:
      2.0

  - ### register

    <U extends T> NamedDomainObjectProvider<U> register(String name, Class<U> type, Action<? super U> configurationAction) throws InvalidUserDataException
    Defines a new object, which will be created and configured when it is required. A object is 'required' when the object is located using query methods such as `NamedDomainObjectCollection.getByName(String)` or when `Provider.get()` is called on the return value of this method.

    It is generally more efficient to use this method instead of `create(String, Class, Action)` or `create(String, Class)`, as those methods will eagerly create and configure the object, regardless of whether that object is required for the current build or not. This method, on the other hand, will defer creation and configuration until required.

    This operation is lazy, the returned element is NOT realized. A `lazy wrapper` is returned, allowing to continue to use it with other lazy APIs.

    Type Parameters:
      `U` - The object type
    Parameters:
      `name` - The name of the object.
      `type` - The object type.
      `configurationAction` - The action to run to configure the object. This action runs when the object is required.
    Returns:
      A `Provider` whose value will be the object, when queried.
    Throws:
      `InvalidUserDataException` - If a object with the given name already exists in this project.
    Since:
      4.10

  - ### register

    <U extends T> NamedDomainObjectProvider<U> register(String name, Class<U> type) throws InvalidUserDataException
    Defines a new object, which will be created when it is required. A object is 'required' when the object is located using query methods such as `NamedDomainObjectCollection.getByName(String)` or when `Provider.get()` is called on the return value of this method.

    It is generally more efficient to use this method instead of `create(String, Class, Action)` or `create(String, Class)`, as those methods will eagerly create and configure the object, regardless of whether that object is required for the current build or not. This method, on the other hand, will defer creation until required.

    This operation is lazy, the returned element is NOT realized. A `lazy wrapper` is returned, allowing to continue to use it with other lazy APIs.

    Type Parameters:
      `U` - The object type
    Parameters:
      `name` - The name of the object.
      `type` - The object type.
    Returns:
      A `Provider` whose value will be the object, when queried.
    Throws:
      `InvalidUserDataException` - If a object with the given name already exists in this project.
    Since:
      4.10