diff --git a/autovalue/pom.xml b/autovalue/pom.xml
index e5b0841807..3aa645002b 100644
--- a/autovalue/pom.xml
+++ b/autovalue/pom.xml
@@ -18,10 +18,29 @@
auto-value
${auto-value.version}
+
+ com.google.auto.factory
+ auto-factory
+ ${auto-factory.version}
+
+
+ com.google.guava
+ guava
+
+
+
+
+
+ com.google.inject
+ guice
+ ${guice.version}
+
1.3
+ 1.0-beta5
+ 4.2.0
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/App.java b/autovalue/src/main/java/com/baeldung/autofactory/App.java
new file mode 100644
index 0000000000..8e911e222a
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/App.java
@@ -0,0 +1,21 @@
+package com.baeldung.autofactory;
+
+import com.baeldung.autofactory.model.Camera;
+import com.baeldung.autofactory.model.Phone;
+import com.baeldung.autofactory.model.PhoneFactory;
+import com.baeldung.autofactory.modules.SonyCameraModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+public class App {
+
+ public static void main(String[] args) {
+ PhoneFactory phoneFactory = new PhoneFactory(() -> new Camera("Unknown", "XXX"));
+ Phone simplePhone = phoneFactory.create("other parts");
+
+ Injector injector = Guice.createInjector(new SonyCameraModule());
+ PhoneFactory injectedFactory = injector.getInstance(PhoneFactory.class);
+ Phone xperia = injectedFactory.create("Xperia");
+ }
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/CustomStorage.java b/autovalue/src/main/java/com/baeldung/autofactory/CustomStorage.java
new file mode 100644
index 0000000000..924a23ebfe
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/CustomStorage.java
@@ -0,0 +1,12 @@
+package com.baeldung.autofactory;
+
+import com.baeldung.autofactory.custom.SmartPhone;
+
+/**
+ * @author aiet
+ */
+public interface CustomStorage {
+
+ SmartPhone customROMInGB(int romSize);
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java b/autovalue/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java
new file mode 100644
index 0000000000..f4c430e953
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java
@@ -0,0 +1,10 @@
+package com.baeldung.autofactory.custom;
+
+/**
+ * @author aiet
+ */
+public abstract class AbstractFactory {
+
+ abstract CustomPhone newInstance(String brand);
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java b/autovalue/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java
new file mode 100644
index 0000000000..b1e2fdef54
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java
@@ -0,0 +1,16 @@
+package com.baeldung.autofactory.custom;
+
+import com.google.auto.factory.AutoFactory;
+
+/**
+ * @author aiet
+ */
+@AutoFactory(extending = AbstractFactory.class)
+public class CustomPhone {
+
+ private final String brand;
+
+ public CustomPhone(String brand) {
+ this.brand = brand;
+ }
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java b/autovalue/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java
new file mode 100644
index 0000000000..d94576ecc6
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java
@@ -0,0 +1,18 @@
+package com.baeldung.autofactory.custom;
+
+import com.baeldung.autofactory.CustomStorage;
+import com.google.auto.factory.AutoFactory;
+
+/**
+ * @author aiet
+ */
+@AutoFactory(className = "SamsungFactory", allowSubclasses = true, implementing = CustomStorage.class)
+public class SmartPhone {
+
+ private int romSize;
+
+ public SmartPhone(int romSize) {
+ this.romSize = romSize;
+ }
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/model/Camera.java b/autovalue/src/main/java/com/baeldung/autofactory/model/Camera.java
new file mode 100644
index 0000000000..269148b690
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/model/Camera.java
@@ -0,0 +1,24 @@
+package com.baeldung.autofactory.model;
+
+/**
+ * @author aiet
+ */
+public class Camera {
+
+ private final String manufacturer;
+ private final String serial;
+
+ public Camera(String manufacturer, String serial) {
+ this.manufacturer = manufacturer;
+ this.serial = serial;
+ }
+
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public String getSerial() {
+ return serial;
+ }
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java b/autovalue/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java
new file mode 100644
index 0000000000..9ec6413e1c
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java
@@ -0,0 +1,38 @@
+package com.baeldung.autofactory.model;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+/**
+ * @author aiet
+ */
+public class ClassicPhone {
+
+ private final String dialpad;
+ private final String ringer;
+ private String otherParts;
+
+ @AutoFactory
+ public ClassicPhone(@Provided String dialpad, @Provided String ringer) {
+ this.dialpad = dialpad;
+ this.ringer = ringer;
+ }
+
+ @AutoFactory
+ public ClassicPhone(String otherParts) {
+ this("defaultDialPad", "defaultRinger");
+ this.otherParts = otherParts;
+ }
+
+ public String getDialpad() {
+ return dialpad;
+ }
+
+ public String getRinger() {
+ return ringer;
+ }
+
+ public String getOtherParts() {
+ return otherParts;
+ }
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/model/Phone.java b/autovalue/src/main/java/com/baeldung/autofactory/model/Phone.java
new file mode 100644
index 0000000000..83c2ba4a0e
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/model/Phone.java
@@ -0,0 +1,34 @@
+package com.baeldung.autofactory.model;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+import javax.inject.Named;
+
+/**
+ * @author aiet
+ */
+@AutoFactory
+public class Phone {
+
+ private Camera camera;
+ private String otherParts;
+
+ public Phone(@Provided @Named("Sony") Camera camera, String otherParts) {
+ this.camera = camera;
+ this.otherParts = otherParts;
+ }
+
+ /* required when used as a base class for AutoFactory */
+ public Phone() {
+ }
+
+ public Camera getCamera() {
+ return camera;
+ }
+
+ public String getOtherParts() {
+ return otherParts;
+ }
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java b/autovalue/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java
new file mode 100644
index 0000000000..dc04ac4a0a
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java
@@ -0,0 +1,22 @@
+package com.baeldung.autofactory.modules;
+
+import com.baeldung.autofactory.model.Camera;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+import javax.inject.Named;
+
+/**
+ * @author aiet
+ */
+public class SonyCameraModule extends AbstractModule {
+
+ private static int SONY_CAMERA_SERIAL = 1;
+
+ @Named("Sony")
+ @Provides
+ Camera cameraProvider() {
+ return new Camera("Sony", String.format("%03d", SONY_CAMERA_SERIAL++));
+ }
+
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java b/autovalue/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java
new file mode 100644
index 0000000000..e0ee8879a5
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java
@@ -0,0 +1,22 @@
+package com.baeldung.autofactory.provided;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javafx.scene.Camera;
+
+import javax.inject.Provider;
+
+/**
+ * @author aiet
+ */
+@AutoFactory
+public class IntermediateAssembler {
+
+ private final Provider camera;
+ private final String otherParts;
+
+ public IntermediateAssembler(@Provided Provider camera, String otherParts) {
+ this.camera = camera;
+ this.otherParts = otherParts;
+ }
+}
diff --git a/autovalue/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java b/autovalue/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java
new file mode 100644
index 0000000000..cc304b7c9e
--- /dev/null
+++ b/autovalue/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java
@@ -0,0 +1,18 @@
+package com.baeldung.autofactory.provider;
+
+import com.baeldung.autofactory.model.Camera;
+import com.google.inject.Provider;
+
+/**
+ * @author aiet
+ */
+public class SonyCameraProvider implements Provider {
+
+ private static int sonyCameraSerial = 1;
+
+ @Override
+ public Camera get() {
+ return new Camera("Sony", String.format("%03d", sonyCameraSerial++));
+ }
+
+}