docs/versioned_docs/version-0.17.2/api/constructors.mdx
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Every Dagger module has a constructor. The default one is generated automatically and has no arguments.
It's possible to write a custom constructor. The mechanism to do this is SDK-specific.
This is a simple way to accept module-wide configuration, or just to set a few attributes without having to create setter functions for them.
The default constructor for a module can be overridden by registering a custom constructor. Its parameters are available as flags in the dagger command directly.
:::important Dagger modules have only one constructors. Constructors of custom types are not registered; they are constructed by the function that chains them. :::
Here is an example module with a custom constructor:
<Tabs groupId="language"> <TabItem value="Go">:::info
In the Python SDK, the @dagger.object_type decorator wraps @dataclasses.dataclass, which means that an __init__() method is automatically generated, with parameters that match the declared class attributes.
:::
The code listing above is an example of an object that has typed attributes.
If a constructor argument needs an asynchronous call to set the default value, it's
possible to replace the default constructor function from __init__() to
a factory class method named create, as in the following code listing:
:::warning
This factory class method must be named create.
:::
:::info
In the PHP SDK the constructor must be the magic method __construct.
As with any method, only public methods with the #[DaggerFunction] attribute will be registered with Dagger.
:::
</TabItem>
<TabItem value="Java">
:::info In the Java SDK, the constructor must be public. A public empty constructor is also required in order to create the object from the serialized data. ::: </TabItem> </Tabs>
Here is an example call for this Dagger Function:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c '. --name=Foo | message' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." . --name=Foo | message ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call --name=Foo message ``` </TabItem> </Tabs>The result will be:
Hello, Foo!
:::important If you plan to use constructor fields in other module functions, ensure that they are declared as public (in Go and TypeScript). This is because Dagger stores fields using serialization and private fields are omitted during the serialization process. As a result, if a field is not declared as public, calling methods that use it will produce unexpected results. :::
Constructors can be passed both simple and complex types (such as Container, Directory, Service etc.) as arguments. Default values can be assigned in both cases.
Here is an example of a Dagger module with a default constructor argument of type Container:
For default values that are more complex, dynamic or just mutable, use a factory function without arguments in dataclasses.field(default_factory=...):
This default value can also be assigned directly in the field:
:::important
When assigning default values to complex types in TypeScript, it is necessary to use the ?? notation for this assignment. It is not possible to use the classic TypeScript notation for default arguments because the argument in this case is not a TypeScript primitive.
:::
It is necessary to explicitly declare the type even when a default value is assigned, so that the Dagger SDK can extend the GraphQL schema correctly.
Here is an example call for this Dagger Function:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c version ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." version ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call version ``` </TabItem> </Tabs>The result will be:
VERSION_ID=3.14.0