What is the ObjectFactory service in Gradle, and how do you obtain an instance of it?
answer
- factory for Gradle model types
- @Inject or project.objects
- can't `new` a Property
- property/listProperty/fileProperty/newInstance
- feeds the lazy Provider model
basics
~10 sObjectFactory 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 linesabstract class MyTask @Inject constructor(
private val objects: ObjectFactory
) : DefaultTask() {
@get:Input
val tag: Property<String> = objects.property(String::class.java)
}go deeper
Know it creates Property/FileCollection/etc. and is reached via project.objects or @Inject.
Explain why new doesn't work and list the main factory methods.
Tie it to lazy evaluation, build-dependency tracking, and configuration-cache correctness; prefer injection.
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).