Dynamicaly instanciate class from name with injector - java

Context
I develop, for my company a software that classifies phishing and malware containing website thanks to multiple feature extraction algorithm.
Once features are extracted we use a pool of empirical and machine learning classifiers. We choose among them thanks to election function of our own.
the code
Basically we have our classifier classes that implement the AnalysisFunction contract.
public abstract class AnalysisFunction {
abstract public StatusType analyze(List<TokenEntity> tokens);
abstract public double getPhishingProbability(List<TokenEntity> tokens);
}
Our pool of classifier is contained by a "pool" that implements AnalysisFunction.
public class PoolAnalysisFunction extends AnalysisFunction{
private final List<AnalysisFunction> candidates;
private final ChoiceFunction choice;
private static final Logger LOG = LogManager.getLogger(PoolAnalysisFunction.class);
public PoolAnalysisFunction(List<AnalysisFunction> candidates, ChoiceFunction choice) {
this.candidates = candidates;
this.choice = choice;
}
#Override
public StatusType analyze(List<TokenEntity> tokens) {
try {
return choice.chooseAmong(candidates, tokens).analyze(tokens);
} catch (ImpossibleChoiceException e){
LOG.fatal("Not enough analysis function.", e);
return StatusType.CLEAN;
}
}
#Override
public double getPhishingProbability(List<TokenEntity> tokens) {
try {
return choice.chooseAmong(candidates, tokens).getPhishingProbability(tokens);
} catch (ImpossibleChoiceException e){
LOG.fatal("Not enough analysis function.", e);
return 0;
}
}
}
To ease the deployment and testing of new function, we want to make our pool fully customizable and instanciate every function by its name. To achieve this purpose we have a key in our property file that is like analysis.pool.functions=com.vadesecure.analysis.empirical.Function1,com.vadesecure.analysis.machine.AutomaticClassifier1.
I want to instantiate my functions thanks to that.
My problem is that those classifiers depend on different things such as custom configuration object and machine learning model.
I would like to inject those dependencies that are already bound in my hk2 injector.
import org.glassfish.hk2.api.Factory;
public class PoolFunctionFactory implements Factory<AnalysisFunction> {
private final PoolAnalysisParameters parameters;
private static final Logger LOG = LogManager.getLogger(PoolAnalysisFunction.class);
#Inject
public PoolFunctionFactory(PoolAnalysisParameters parameters) {
this.parameters = parameters;
}
#Override
public AnalysisFunction provide() {
try {
Class<?> choice = Class.forName(parameters.getChoiceFunctionFQDN());
ChoiceFunction choiceFunction = new PhishingPriorityChoiceFunction(); // default choice
if(choice.getSuperclass().isInstance(ChoiceFunction.class)){
choiceFunction = (ChoiceFunction) choice.newInstance();
}
List<AnalysisFunction> analysisFunctions = new LinkedList<>();
// I want to instantiate here
}
return new PoolAnalysisFunction(analysisFunctions, choiceFunction);
} catch (ClassNotFoundException|IllegalAccessException|InstantiationException e){
LOG.fatal(e, e);
}
return null;
}
#Override
public void dispose(AnalysisFunction analysisFunction) {
LOG.trace(String.format("%s end of life", analysisFunction));
}
}
On example of model-dependant classifier is :
public class SVMF2AnalysisFunction extends AnalysisFunction {
private final SVMContainer modelContainer;
private double probability = 0.0;
private double threshold = 0.9;
#Inject // i build this model in a parallel thread
public SVMF2AnalysisFunction(SVMContainer modelContainer) {
this.modelContainer = modelContainer;
}
#Override
public StatusType analyze(List<TokenEntity> tokens) {
if (modelContainer.getModel() == null) {
return null;
}
probability = modelContainer.getModel().analyse(tokens.stream());
return probability >= threshold ? StatusType.PHISHING : StatusType.CLEAN;
}
#Override
public double getPhishingProbability(List<TokenEntity> tokens) {
return probability;
}
}
How can I achieve those instanciations.
My first approach was to inject the serviceLocator but i found no documentations for doing this and a colleague said me it was not good.
He told be to document myself about proxies but it doesn't seem to be a good thing for me or perhaps I missed something.

You could just configure all this in your binder. This way you don't need to worry about trying to instantiate everything yourself. Just let HK2 do all the work
#Override
protected void configure() {
bindAsContract(PoolAnalysisFunction.class).in(Singleton.class);
bind(choiceFnClass).to(ChoiceFunction.class);
for (Class<AnalysisFunction> analysisFnClass: analyisFnClasses) {
bind(analysisFnClass).to(AnalysisFunction.class).in(Singleton.class);
}
}
Then you can just inject everything into the PoolAnalysisFunction class, without the need to use a factory.
#Inject
public PoolAnalysisFunction(IterableProvider<AnalysisFunction> candidates,
ChoiceFunction choice) {
this.choice = choice;
this.candidates = new ArrayList<>();
candidates.forEach(this.candidates::add);
}
Notice the IterableProvider class. This is an HK2 class for injecting multiple services bound to the same contract.
Or if you want to use the factory, you could, and just inject the functions into the factory. That way you can make the PoolAnalysisFunction class independent of an HK2 classes (i.e. the InjectableProvider).

Related

Inject several implementations of an abstraction in a class

I hope you're doing well, I have a doubt when I try to create a method that can validate some business rules.
In this case, I have a class
public class ValidationUtils {
final List<CreditValidations> creditValidations;
public ValidationUtils(){
creditValidations = Arrays.asList(
new ValidateAge(),
new ValidateSalary()
);
}
public ValidationRs passAllValidations(Client client){
final var validationsFailed = new ArrayList<String>();
boolean validationResult = false;
for (CreditValidations creditValidationClasses : creditValidations){
validationResult = Boolean.logicalXor(creditValidationClasses .validate(client,validationsFailed),
validationResult);
}
final var rs = new ValidationRs();
rs.setSuccessfulValidations(validationResult);
rs.setValidationsFailed(validationsFailed);
return rs;
}
}
this class has a method called "passAllValidations" That method can evaluate each CreditValidation implementation and join their results, Using this code I don't need to create more methods when I have a new validation, only extends the abstraction and create the new Validation class and inject it in the ValidationUtils constructor.
the abstraction and implementation of CreditValidations look like
public abstract class CreditValidations {
protected final String errorCode;
protected CreditValidations(final String errorCode) {
this.errorCode = errorCode;
}
protected abstract boolean validate(final Client client,final List<String> validationsFailed);
protected boolean evaluateValidation(boolean validationResult, List<String> validationsFailed){
if (!validationResult){
setCode(validationsFailed);
}
return validationResult;
}
protected String getErrorCode() {
return this.errorCode;
}
protected void setCode(List<String> failedValidations) {
failedValidations.add(errorCode);
}
}
public class ValidateAge extends CreditValidations {
public ValidateAge() {
super(CreditValidationErrorEnum.ERROR_VALIDATING_AGE.getCode());
}
#Override
public boolean validate(final Client client, List<String> validationsFailed) {
return this.evaluateValidation(client.getAge() >= 18,validationsFailed);
}
}
in summary, my question is referring to the dependency injection in the class ValidationUtils, I don't know if it way is correct or if Spring Framework has some things that help me to inject all of the CreditValidation implementations and avoid using Array.asList(new NewValidationClass()) or another design pattern which can help.
Thanks in advance.

how to create abstract factory to instantiate objects in java

I would like to create an abstract factory. here is what I tried.
//abstract class Worker
public abstract class Worker {
String phoneNumber;
String firstName;
String lastName;
String workerType;
String ifu;
String imageParth;
//....
public String getWorkerType() {
return workerType;
}
}
// Electrician class which extends worker
package worker.domain.worker;
public class Electrician extends Worker{
public Electrician() {}
public Electrician(String phoneNumber, String firstName, String lastName, String ifu, String workerType,
String imageParth) {
super(phoneNumber, firstName, lastName, ifu,workerType, imageParth);
}
public String getWorkerType() {
return "Electrician";
}
}
//Mason class
package worker.domaine.worker;
public class Mason extends Worker{
public Mason() {};
public Mason(String phoneNumber, String firstName, String lastName, String ifu,String workerType,
String imageParth) {
super(phoneNumber, firstName, lastName, ifu, workerType, imageParth);
}
String getworkerType() {
return "Mason";
}
}
// interface WorkerAbstractFactory
package worker.domaine.worker;
public interface WorkerAbstractFactory {
Worker createWorker(String typeWorker);
}
//
public class WorkerFactory implements WorkerAbstractFactory{
#Override
public Worker createWorker(String typeWorker) {
Worker worker = null;
if(worker != null) {
switch (typeWorker) {
case "Electrician":
Electrician electrician =new Electrician();
electrician = new Electrician (electrician.getPhoneNumber(), electrician.getFirstName(), electrician.getLastName(), electrician.getIfu(), electrician.getWorkerType(),electrician.getImageParth());
case "Mason":
Mason mason =new Mason();
mason = new Mason (mason.getPhoneNumber(), mason.getFirstName(), mason.getLastName(), mason.getIfu(), mason.getworkerType(),mason.getImageParth());
}}
//app class
public class WorkerFactoryProvider {
public static WorkerAbstractFactory getWorkerFactory(String workerCategory) {
//WorkerFactory workerFactory = new WorkerFactory();
WorkerFactory workerFactory = new WorkerFactory();
if (workerCategory != null) {
switch (workerCategory) {
case "Electrician":
Worker worker1 = workerFactory.createWorker("Electrician");
worker1.getWorkerType();
String a=worker1.getWorkerType();
System.out.println(a);
case "Mason":
Worker worker2 = workerFactory.createWorker("Mason");
worker2.getWorkerType();
String b=worker2.getWorkerType();
System.out.println(b);
}
}
return null;
}
do you think it could work like that? now, if I really want a concrete object, how could it be done? because I would like to write for example a method to calculate the pay of each worker according to type for example how could I use my abstract Factory in the method to return me each type.
You have a single class hierarchy of Worker types. To instantiate those you can just use a standalone factory class, you don't need an abstract factory here. For example this would be sufficient:
public class WorkerFactory {
public Worker createWorker(String workerType) {
switch (workerType) {
case "Electrician": return new Electrician();
case "Mason": return new Mason();
}
}
}
The abstract factory pattern is more elaborate, and allows injecting different concrete factories for related hierarchies of objects, so that the client doesn't need to be aware of the difference. For example you could have an abstract TransportationFactory:
interface Transportation {
void travelTo(String destination);
}
interface TransportationFactory {
Transportation simple();
Transportation luxurious();
}
And two concrete implementations (matching two different but similar class hierarchies):
class WaterTransportationFactory {
Transportation simple() {
return new Kayak();
}
Transportation luxurious() {
return new Yacht();
}
}
And:
class LandTransportationFactory {
Transportation simple() {
return new Bike();
}
Transportation luxurious() {
return new RaceCar();
}
}
The benefit of this pattern is that the client can be configured to use water or land transportation (or a new air transportation that is added later) without the need to undergo any changes:
class Client {
private TransportationFactory transportationFactory;
public Client(TransportationFactory transportationFactory) {
this.transportationFactory = transportationFactory;
}
public void travel(String destination) {
transportationFactory.simple().travelTo(destination);
}
public void travelInStyle(String destination) {
transportationFactory.luxurious().travelTo(destination);
}
}
EDIT: You could change the simple/luxurious methods to match the style of your example with the getWorkerType method. I prefer to avoid the conditional logic if possible and let the created classes determine their availability themselves. This decouples even further, allowing hierarchy members to be added with minimal code changes:
enum TransportationType {
SIMPLE, LUXURIOUS
}
interface Transportation {
void travelTo(String destination);
// allow the class to specify its own type
TransportationType getType();
}
// intermediate interface to distinguish Water from Land
interface WaterTransportation extends Transportation {
}
class Kayak implements WaterTransportation {
void travelTo(String destination) {
// splash splash
}
TransportationType getType() {
return TransportationType.SIMPLE;
}
}
class WaterTransportationFactory {
private WaterTransportation[] waterTransportations;
// Inject all available beans implementing WaterTransportation
// e.g. using Spring or some other dependency injection mechanism
public WaterTransportationFactory(WaterTransportation[] waterTransportations) {
this.waterTransportations = waterTransportations;
}
public Transportation create(TransportationType type) {
for(WaterTransportation waterTransportation : waterTransportations) {
if (waterTransportation.getType() == type) {
// we are returning the same instance every time
// this could be ok for singleton beans
// but if you really need a fresh instance you could use builders (see below)
return waterTransportation;
}
}
throw new IllegalArgumentException("No implementation for WaterTransportation type=" + type);
}
}
An alternative with builders:
KayakBuilder implements WaterTransportationBuilder {
KayakBuilder name(String name) { ... };
KayakBuilder weight(String weightInKg) { ... };
KayakBuilder year(String yearBuilt) { ... };
KayakBuilder speed(String averageSpeed) { ... };
Kayak build() { return kayak; }
}
For more on Builders see this full exposition of the Builder pattern
class WaterTransportationFactory {
private WaterTransportationBuilder[] builders;
// Inject all available WaterTransportationBuilders
// e.g. using Spring or some other dependency injection mechanism
public WaterTransportationFactory(WaterTransportationBuilder[] builders) {
this.builders = builders;
}
// extra arguments can be passed to build the instance
public Transportation create(TransportationType type, String name, int weightInKg, int yearBuilt, int averageSpeed) {
for(WaterTransportationBuilder builder: builders) {
if (builder.getType() == type) {
return builder
.name(name)
.weight(weightInKg)
.year(yearBuilt)
.speed(averageSpeed)
.build();
}
}
throw new IllegalArgumentException("No implementation for WaterTransportation type=" + type);
}
}

Wire collection of objects dynamically in Guice

Guice newbie here, with a complicated scenario.
My company has a large number of constants of a given type (let's call them Thingy) that belong to different teams and are maintained in different parts of our application. However, we need to have a central registry that knows about all of them (let's call this the ThingyService). I am writing a base module that teams can either extend or install, with the purpose of allowing a team to register their Thingys, and giving them access to the ThingyService. This module takes as parameter a list of classes from which I can extract the Thingy constants, this part is working fine.
What I don't understand is how I can a) make each module know about each other module's list of Thingys and b) how I can create my ThingyService as a singleton that contains all of my Thingys. I have experimented with shared static state and with ThreadLocals, but I keep either breaking tests or breaking my main (play) application. In my naive understanding of Guice, I think I need a MultiBinder for the Thingys, but I don't see how I can share that between modules. Here's what I'd like to do:
class ThingyModule extends AbstractModule{
final Set<Class<?>> myThingyClasses; // this is populated in the constructor
private Set<Thingy> extractThingiesFromThingyClasses(){
// I have this working
}
#Provides #Singleton ThingyService thingyService(
Set<Thingy> thingys // all thingys, from all such modules
){
return new ThingyService(thingys);
}
protected void configure(){
extractThingiesFromThingyClasses().forEach(thingy->
// bind thingy to a global MultiBinder?
);
}
}
How can I make my ThingyService unique and global, with all the Thingys from the entire application? Note: I don't necessarily need my Thingys to be managed by Guice, the only place I need them is in ThingyService. Also, this is a play / scala application if that makes a difference, but my ThingyModule code lives in a library written in Java.
It turns out I omitted one important detail, Thingy has a type parameter, it's actually Thingy<T>, and that's the reason it didn't work before. By cheating and registering Thingy as raw type, and then also injecting it as raw type, I got it to work.
Here is a complete working example using JUnit 5 and AssertJ:
class ThingyModuleTest {
static class Thingy<T>{
private final T value;
Thingy(final T value) {this.value = value;}
#Override public boolean equals(final Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
final Thingy<?> thingy = (Thingy<?>) o; return Objects.equals(value, thingy.value); }
#Override public int hashCode() { return Objects.hash(value); }
}
#Singleton
static class ThingyService{
final Set<Thingy<?>> thingies;
#SuppressWarnings({"unchecked", "rawtypes"}) #Inject
ThingyService(Set<Thingy> thingies) {
this.thingies = ImmutableSet.copyOf((Set)thingies);
}
public Set<Thingy<?>> getThingies() { return thingies; }
}
abstract static class ThingyModule extends AbstractModule {
private final Set<Class<?>> classesToScan;
public ThingyModule(Class<?>... classes) {
this.classesToScan = ImmutableSet.copyOf(classes);
}
private Set<Thingy<?>> scanForThingies(){
return classesToScan.stream()
.flatMap(c-> Arrays.stream(c.getDeclaredFields()))
.filter(f->f.getType().isAssignableFrom(Thingy.class))
.filter(f-> Modifier.isStatic(f.getModifiers())&&Modifier.isFinal(f.getModifiers()))
.map(this::readThingy)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());
}
#SuppressWarnings("unchecked")
private Optional<Thingy<?>> readThingy(final Field field) {
try{
field.setAccessible(true);
return Optional.ofNullable(field.get(null))
.filter(Thingy.class::isInstance)
.map(Thingy.class::cast);
} catch (IllegalAccessException e) { return Optional.empty(); }
}
#Override protected void configure() {
bind(ThingyService.class);
#SuppressWarnings("rawtypes") Multibinder<Thingy> multibinder = Multibinder.newSetBinder(binder(), Thingy.class);
scanForThingies().forEach(thingy -> multibinder.addBinding().toInstance(thingy));
}
}
static class ThingyModule1 extends ThingyModule {
public ThingyModule1() { super(Thingies1.class); }
static class Thingies1{
static final Thingy<Boolean> BooleanThingy = new Thingy<>(true);
static final Thingy<Integer> IntThingy = new Thingy<>(123);
}
}
static class ThingyModule2 extends ThingyModule {
public ThingyModule2() { super(Thingies2.class); }
static class Thingies2{
static final Thingy<String> StringThingy = new Thingy<>("hello");
static final Thingy<Long> LongThingy = new Thingy<>(123L);
}
}
#Test void validateThingyService() {
ThingyService thingyService = Guice.createInjector(new ThingyModule1(), new ThingyModule2())
.getProvider(ThingyService.class)
.get();
assertThat(thingyService).isNotNull()
.extracting(ts -> ImmutableList.copyOf(ts.getThingies()))
.asList()
.containsExactlyInAnyOrder(BooleanThingy, IntThingy, StringThingy, LongThingy);
}
}
I will mark this answer as accepted until somebody else provides a more idiomatic one.

Object inheritance - refactoring problem - possibility to create flexible service

It should be pretty easy but obviously I am lacking of basic knowlege.
I have a service which is ment to create ticket in BugTracking systems.
Creating plugins is pretty stright forward. there is an interface
public interface BugTracker {
boolean createAndSendIssue(Issue issue);
boolean updateAndSendIssue(Issue issue);
boolean closeIssue(Issue issue);
}
and API client for JIRA:
#Component
public class JiraClient implements BugTracker {
#Override
public boolean createAndSendIssue(Issue issue) {
//Logic for using JIRA REST API
return false;
}
#Override
public boolean updateAndSendIssue(Issue issue) {
//Logic for using JIRA REST API
return false;
}
#Override
public boolean closeIssue(Issue issue) {
//Logic for using JIRA REST API
return false;
}
}
API CLient for Bugzilla:
#Component
public class BugzillaClient implements BugTracker {
#Override
public boolean createAndSendIssue(Issue issue) {
//Logic for using BUGZILLA REST API
return false;
}
#Override
public boolean updateAndSendIssue(Issue issue) {
//Logic for using BUGZILLA REST API
return false;
}
#Override
public boolean closeIssue(Issue issue) {
//Logic for using BUGZILLA REST API
return false;
}
}
Problem occurs on the Service which is handling MVC. Piece of it looks like:
#Service
public class BugTrackerService {
private final BugzillaClient bugzillaClient;
private final JiraClient jiraClient;
private static final String JIRA_TYPE = "Jira";
private static final String BUGZILLA_TYPE = "Bugzilla";
#Autowired
BugTrackerService(BugzillaClient bugzillaClient, JiraClient jiraClient) {
this.bugzillaClient = bugzillaClient;
this.jiraClient = jiraClient;
}
boolean processIssueTicketRequest(Issue issue){
if ( issue.getBugTrackerType().bugTrackingSystemType.name.equals(JIRA_TYPE)) {
return jiraClient.createAndSendIssue(issue);
} else if (issue.getBugTrackerType().bugTrackingSystemType.name.equals(BUGZILLA_TYPE)){
return bugzillaClient.createAndSendIssue(issue);
} else {
return false;
}
}
}
is it somehow possible to create method BugTrackerService.processIssueTicketRequest without all clients autowired? At this moment it is not so much of a problem but after integrating with more and more systems this service will become complex.
Depending on how reusable you want implementations to be, I'd probably put the logic of checking whether the given issue is of matching typing into the interface, eg
boolean canWorkWithGivenIssue(Issue issue);
With that in place then you don't need to know actual types of trackers you dispatch on, and merely aggregate them into the list. Spring will do that for you if you annotate a collection with #Autowired, in which cases it will provide you all the beans with matching type. Your service then could look like this
#Autowired List<BugTracker> trackers; //autowired on field for brevity
boolean processIssueTicketRequest(Issue issue){
for (BugTracker t : trackers)
if (t.canWorkWithGivenIssue(issue))
return t.createAndSendIssue(issue);
return false;
}
Turn the type into an enum and let the BugTracker decide if it can handle it. Then inject a collection of all BugTracker instances, iterate over them and if it supports the type call the appropriate method.
public enum SystemType { JIRA, BUGZILLA }
Then add a method, for instance supports(Issue issue), to your BugTracker.
boolean supports(Issue issue);
In the implementations check if it can be handled, for instance in the JiraClient do something like this.
public boolean supports(Issue issue) {
return JIRA == issue.getBugTrackerType();
}
Then in your BugTrackerService get a list of all BugTracker instances, iterate and call the appropriate one.
#Service
public class BugTrackerService {
private final List<BugTracker> bugTrackers;
BugTrackerService(List<BugTracker> bugTrackers) {
this.bugTrackers=bugTrackers;
}
boolean processIssueTicketRequest(Issue issue){
for (BugTracker bugTracker : this.bugTrackers) {
if (bugTracker.supports(issue) ) {
bugTracker.createAndSendIssue(issue);
return true;
}
}
return false;
}
}
Now you are as flexible as you want to be and can support as many as you want.
You can pass on the responsibility of finding out the correct implementation of BugTracker to a BugTrackerFactory.
#Component
class BugTrackerFactory {
#Autowired
private final BugzillaClient bugzillaClient;
#Autowired
private final JiraClient jiraClient;
private static final String JIRA_TYPE = "Jira";
private static final String BUGZILLA_TYPE = "Bugzilla";
public BugTracker getBugTracker(String type) {
if (JIRA_TYPE.equals(type)) {
return jiraClient;
} else if (BUGZILLA_TYPE.equals(type)) {
return bugzillaClient;
} else {
// throw some exception
}
}
}
BugTrackerService :
#Service
public class BugTrackerService {
private final BugTrackerFactory bugTrackerFactory;
#Autowired
BugTrackerService(BugTrackerFactory bugTrackerFactory) {
this.bugTrackerFactory = bugTrackerFactory;
}
boolean processIssueTicketRequest(Issue issue){
return bugTrackerFactory.getBugTracker(issue.getBugTrackerType().bugTrackingSystemType.name).createAndSendIssue(issue);
}
}

Tapestry: Inject at runtime

again a small problem by understanding "how tapestry works".
I've got a Tapestry component (in this case a value encoder):
public class EditionEncoder implements ValueEncoder<Edition>, ValueEncoderFactory<Edition> {
#Inject
private IEditionManager editionDao;
public EditionEncoder(IEditionManager editionDao) {
this.editionManager = editionDao;
}
#Override
public String toClient(Edition value) {
if(value == null) {
return "";
}
return value.getName();
}
#Override
public Edition toValue(String clientValue) {
if(clientValue.equals("")) {
return null;
}
return editionManager.getEditionByName(clientValue);
}
#Override
public ValueEncoder<Edition> create(Class<Edition> type) {
return this;
}
}
Injecting the the Manager is not working, because the Encoder is created within a page like that:
public void create() {
editionEncoder = new EditionEncoder();
}
casued by this, i'm forced to use this ugly solution:
#Inject
private IEditionManager editionmanager;
editionEncoder = new EditionEncoder(editionManager);
Is there a better way to inject components during runtime or is there a better solution in general for it?
Thanks for your help in advance,
As soon as you use "new" then tapestry-ioc is not involved in object creation and can't inject. You should inject everything and never use "new" for singleton services. This is true for all ioc containers, not just tapestry-ioc.
Also if you put #Inject on a field then you don't also need a constructor to set it. Do one or the other, never both.
You should do something like this:
public class MyAppModule {
public void bind(ServiceBinder binder) {
binder.bind(EditionEncoder.class);
}
}
Then in your page/component/service
#Inject EditionEncoder editionEncoder;
If you wanted to put your own instantiated objects in there you can do
public class MyServiceModule {
public void bind(ServiceBinder binder) {
binder.bind(Service1.class, Service1Impl.class);
binder.bind(Service2.class, Service2Impl.class);
}
public SomeService buildSomeService(Service1 service1, Service2 service2, #AutoBuild Service3Impl service3) {
Date someDate = new Date();
return new SomeServiceImpl(service1, service2, service3, someDate);
}
}

Categories