Step 1. Add the JitPack repository to your build file
Add it in your root settings.gradle at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Add it in your settings.gradle.kts at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
Add to pom.xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add it in your project.clj at the end of repositories:
:repositories [["jitpack" "https://jitpack.io"]]
Step 2. Add the dependency
dependencies {
implementation 'com.github.mobilecashout:dockyard:2.0.10'
}
dependencies {
implementation("com.github.mobilecashout:dockyard:2.0.10")
}
<dependency>
<groupId>com.github.mobilecashout</groupId>
<artifactId>dockyard</artifactId>
<version>2.0.10</version>
</dependency>
libraryDependencies += "com.github.mobilecashout" % "dockyard" % "2.0.10"
:dependencies [[com.github.mobilecashout/dockyard "2.0.10"]]
Centralized component discovery made easy.
Dockyard is a simple, compile-time component discovery service for Java applications that seamlessly integrates with dependency injection frameworks like Dagger and Guice. It is developed and tested with Dagger 2, used internally by MobileCashout.
Add the JitPack repository:
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
Add the dependency:
<dependency>
<groupId>com.github.mobilecashout</groupId>
<artifactId>dockyard</artifactId>
<version>VERSION</version>
</dependency>
Consider having an interface:
interface MyValueProvider {}
It is common you will have one or more implementations of mentioned interface for many different reasons. The specific use case of Dockyard is when you have more than one implementation and you require all of those implementations to do a certain task, but do not want to manually inject all of them, and find it would be easier to just have a list of those implementations you can then access later for whatever reason.
This can be achieved using Dockyard, namely by annotating these implementations with @Dockyard
annotation -
they will then be picked up by Dockyard annotation processor and registered in a generated container.
Consider this example:
import com.mobilecashout.dockyard.Dockyard;
interface MyValueProvider {}
@Dockyard(MyValueProvider.class)
class SimpleValueProvider implements MyValueProvider{}
@Dockyard(MyValueProvider.class)
class ComplexValueProvider implements MyValueProvider{}
Given that you have two classes like this in your codebase, Dockyard would pick them up and generate a source file containing a special container class:
import javax.inject.Inject;
//...
import com.mobilecashout.dockyard.DockyardContainer;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class MyValueProviderDockyard implements DockyardContainer {
@Inject
protected SimpleValueProvider a0;
@Inject
protected ComplexValueProvider a1;
protected List<MyValueProvider> instances = null;
@Inject
public MyValueProviderDockyard() {
}
public List<MyValueProvider> getAll() {
if (null == instances) {
instances = Collections.unmodifiableList(Arrays.asList(new MyValueProvider[] {a0,a1}));
}
return instances;
}
}
If you look at the generated code, you can notice the @Inject
annotation -
Dockyard is designed only to locate and compose the components, not to instantiate them.
Instantiation should be done in your dependency injection container.
In both Dagger and Guice this can be done by simply injecting the *Dockyard
component as a
dependency.
Name of the generated class will be determined by the class you are binding the component to,
in this case, it is interface MyValueProvider
, therefore the name of the container -
MyValueProviderDockyard
.
You can not mark more than 65,534 classes for the same Dockyard container as this is the limit of fields a Java class can have. In the unlikely scenario this is necessary, for example, in case of generated classes etc, you will need to split them in multiple Dockyard containers and unify them back in code.
You can add single class to multiple containers like this:
@Dockyard({MyValueProvider.class, MyOtherProvider.class})
Note, that you can only add class to container if the class does implement the interface or extends container class somewhere along the chain.
Dockyard will attach @Named
annotation to the field being injected in to the container if you add a name
key to Dockyard annotaiton like this.
This allows you to inject named instance of the given class if it is named in your dependency injection container giving slightly more
flexibility as to which instance should be used.
@Dockyard(value = {MyValueProvider.class}, name = "some_name")
Oct 15, 2017
Oct 14, 2017
Oct 14, 2017
Singleton
.Oct 14, 2017
DockyardContainer.getAll()
now returns List<T>
instead of T[]
Array.Mar 9, 2017
Apache 2.0 License.