skip to content

ObjectFactory & Managed Types

Injecting ObjectFactory, creating instances with newInstance, abstract getters as managed properties, and file and directory properties. Interviewers ask because managed types are the reason modern task classes are abstract.

on this pageshow

questions

5

What is the ObjectFactory service in Gradle, and how do you obtain an instance of it?

level: juniorimportance: must knowfreq 55%

answer

  1. factory for Gradle model types
  2. @Inject or project.objects
  3. can't `new` a Property
  4. property/listProperty/fileProperty/newInstance
  5. feeds the lazy Provider model

basics

~10 s

ObjectFactory is a Gradle service that creates instances of model objects like Property, FileCollection, and custom managed types. You get it via @Inject in a constructor or through project.objects.

solid answer

~40 s

`ObjectFactory` is a built-in Gradle service for creating instances of Gradle's model object types — `Property<T>`, `ListProperty<T>`, `RegularFileProperty`, `FileCollection`, and your own managed types via `newInstance()`. It exists because these types must be created by Gradle (not `new`) so the runtime can wire in change-tracking, lazy evaluation, and dependency awareness. You obtain it two ways: inject it with `@Inject` into a constructor of a task, plugin, or extension (`@Inject constructor(private val objects: ObjectFactory)`), or access `project.objects` directly during configuration. Inside tasks and extensions Gradle prefers injection so the object is decoupled from `Project`. Using `objects.property(String::class.java)` instead of `new` ensures the property participates in Gradle's lazy/Provider machinery and configuration-cache compatibility.

code

kotlin · 6 lines
kotlin
abstract class MyTask @Inject constructor(
    private val objects: ObjectFactory
) : DefaultTask() {
    @get:Input
    val tag: Property<String> = objects.property(String::class.java)
}

go deeper

for a junior

Know it creates Property/FileCollection/etc. and is reached via project.objects or @Inject.

for a middle

Explain why new doesn't work and list the main factory methods.

for a senior

Tie it to lazy evaluation, build-dependency tracking, and configuration-cache correctness; prefer injection.

for a principal

Frame ObjectFactory as the substrate for Gradle's managed-object model and standardize injection patterns across an org's plugin suite.

## What ObjectFactory is `ObjectFactory` is one of Gradle's injectable services. Its job is to **construct instances of Gradle's model object types**. These types — `Property<T>`, `ListProperty<T>`, `MapProperty<T>`, `SetProperty<T>`, `RegularFileProperty`, `DirectoryProperty`, `ConfigurableFileCollection`, `NamedDomainObjectContainer`, and your own *managed types* — cannot be created with a plain constructor (`new`/`SomeType()`). Gradle must create them so it can attach behavior: lazy evaluation, task-dependency tracking, and configuration-cache serialization. ## Why you can't just `new` them `Property<T>` is an interface; there is no public implementation class to instantiate. Gradle generates the implementation at runtime and weaves in machinery (build-dependency tracking, value conventions, finalization). `ObjectFactory` is the factory that produces those generated instances. ## How to obtain it Two idiomatic ways: 1. **Constructor injection** (preferred inside tasks, plugins, extensions). Mark a constructor parameter (or an abstract getter) with `@Inject`. Gradle's dependency-injection container supplies the service. 2. **`project.objects`** — every `Project` exposes the same `ObjectFactory`. Use this in plugin `apply()` code or scripts where you have a `Project` handle. ## Core methods - `property(Class<T>)` → a `Property<T>` - `listProperty(Class<T>)`, `setProperty(...)`, `mapProperty(...)` - `fileProperty()` → `RegularFileProperty`; `directoryProperty()` → `DirectoryProperty` - `fileCollection()` → `ConfigurableFileCollection` - `newInstance(Class, args...)` → an instance of a *managed type* or a class with `@Inject`-able constructor - `named(Class<T>, String)` → a `Named` instance (used for attribute values and variant matching) ```kotlin abstract class GreetingExtension @Inject constructor(objects: ObjectFactory) { val message: Property<String> = objects.property(String::class.java) } ``` ## Relationship to the lazy API Everything `ObjectFactory` produces plugs into the **Provider/Property** lazy-configuration model: values can be set as deferred `Provider`s and only resolved at execution time, which is what makes incremental builds and the configuration cache work.

  • Why can't you instantiate a Property<T> with a normal constructor?
    Property is an interface with no public impl; Gradle generates the implementation at runtime so it can wire in lazy evaluation, build-dependency tracking, and configuration-cache support. ObjectFactory is the factory that returns those instances.
  • When would you prefer project.objects over @Inject?
    Use project.objects in plugin apply() code where you already hold a Project; prefer @Inject inside tasks/extensions so the type doesn't depend on Project and stays configuration-cache friendly.

saying these in an interview costs you the question

  • Claiming you can `new Property()` or instantiate Property impls directly.
  • Confusing ObjectFactory (creates model objects) with ProviderFactory (creates Providers from env/sysprops).

context

open as a page

What is a 'managed type' in Gradle, and how do abstract getters become managed properties?

level: middleimportance: must knowfreq 50%

basics

~10 s

A managed type is a class (usually abstract) where Gradle generates the implementation. Abstract getters returning Property/FileCollection/etc. become managed properties Gradle initializes automatically, so you don't write boilerplate or constructors.

open as a page

What are fileProperty() and directoryProperty() from ObjectFactory, and why use them instead of java.io.File?

level: middleimportance: should knowfreq 42%

basics

~10 s

objects.fileProperty() returns a RegularFileProperty and objects.directoryProperty() a DirectoryProperty — lazy, location-aware wrappers around a file/dir. They defer resolution and track task dependencies, unlike a raw File.

open as a page

What does ObjectFactory.named() do, and when do you use Named types in Gradle?

level: seniorimportance: should knowfreq 30%

basics

~10 s

objects.named(Type, "value") creates an instance of a Named interface subtype carrying that string name. It's used for attribute values like Usage, Category, or custom variant attributes in dependency resolution.

open as a page

How does ObjectFactory.newInstance() work, and how does service injection into the created instance behave?

level: seniorimportance: should knowfreq 28%

basics

~10 s

objects.newInstance(Type, args) creates an instance, generating impls for abstract managed types and supplying constructor @Inject services (like ObjectFactory) plus any extra args you pass. It's how you create nested DSL objects.

open as a page