Dagger with Java AWS Lambda? - dependency-injection

I'm struggling to come up with a solution where I can use Dagger and Lambda. The main issue seems that dependency injection happens in the constructor, while you have to provide at least one 0-arg-constructor in Lambda. How can I overcome this?

The solution I've come up to (and blogged about) is to make your zero-args constructor retrieve the constructed Dagger configuration i.e.:
public Handler() {
this(DaggerConfig.create().serviceLayer());
}
/* test only */ Handler(ServiceLayer service) {
this.service = service;
}

No need to provide 0-arg-constructor. Try lambda event and extend request handler.
guice, spring resolve the dependency on runtime, which might increase your cold start time. On the other hand, dagger2 resolves dependency on compile time.
For more details: https://www.youtube.com/watch?v=plK0zyRLIP8
https://github.com/shivaramani/aws-dagger-lambda

Related

What is the use of requireBinding?

I am relatively new to Guice and trying to understand the usage of requireBinding and when/why to use it.
As per my understanding, while creating an injector Guice goes through the code of configure() method of all the modules and builds a dependency graph.
If Guice builds the dependency graph in itself then why does a module need to add a requireBinding? As long as I could understand the usage of requireBinding is to add an explicit dependency on a class which guice's dependency graph seems to be doing anyway.
I would like to understand that when should we use requireBinding and what is the impact of not using it in a module.
I have read Guice's official documentation and search on all the existing questions on Stackoverflow/any other blog but couldn't find a satisfying answer to the above question.
Adding to the original question.
Looking at the Source code of the AbstractModule the implementation looks like
protected void requireBinding(Key<?> key) {
this.binder().getProvider(key);
}
protected void requireBinding(Class<?> type) {
this.binder().getProvider(type);
}
Which you would assume will not have any side effect as it's a "get" call.
But on the other hand looking it the binder itself it adds some element to a list of elements of type ProviderLookup
public <T> Provider<T> getProvider(Dependency<T> dependency) {
ProviderLookup<T> element = new ProviderLookup(this.getElementSource(), dependency);
this.elements.add(element);
return element.getProvider();
}
I've always though of requireBinding() as a contract for the Module.
You are correct that the graph would eventually fail when you call #get() or tried to inject an object that depends on the binding. However, I believe requireBinding will cause a failure when the Injector is created vs when the object is created (via the injector). When I was at Google, it functioned more as a contract, less as something with consequential behavior.

What is the difference between injection through the constructor and injection through field annotations with Guice?

I have the below code to do dependency injection using Guice. The first one is using constructor injection while the other one is adding #Inject directly above the field. Is there any difference between these two ways? It seems that constructor injection is recommended on the Guice official website.
class BillingService {
private final CreditCardProcessor processor;
private final TransactionLog transactionLog;
#Inject
BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
this.processor = processor;
this.transactionLog = transactionLog;
}
...
}
And:
class BillingService {
#Inject
private final CreditCardProcessor processor;
#Inject
private final TransactionLog transactionLog;
BillingService() {
}
...
}
The differences I would point:
without constructor injection you won't be able to use the final modifier, i.e. your code above won't compile. Commenting the advantages of final members is off-topic here.
with constructor injection all dependencies are kind of mandatory. You won't be able to instantiate the class without knowing about each declared dependency.
writing test cases with constructor injection might be easier (see the answer of The111).
there is another type of DI - setter injection - which can be more naturally mixed with constructor injection (e.g. for separating mandatory and optional dependencies).
Here's one difference. In the latter case, injection is the only way you can completely construct an instance of BillingService. If for whatever reason you need to build one without injection, you can't (using the methods shown, at least).
In the former case, you can still build one the old fashioned way, if you have some reason to want to do that:
new BillingService(someProcessor, someLog);
I've worked on one team that did it one way, and another that did it the other way. In most cases I used injection all the time, even for test. But every once in a while in a unit test I find it convenient to construct something the non-Guicy way, and in those cases the constructor injection does buy you that flexibility.

CDI and multiple instances

I'm just investigating possibilities of DI frameworks and I made some stupid example for it. I have simple service.
public class Service implements ServiceI {
private Source source;
private Translator translator;
#Inject
public Service(Translator translator, Source source) {
this.translator = translator;
this.source = source;
}
I want to have two instances of this service one which is initiated with TranslatorA and SourceA and second which will be injected with different values.
How can one have two instances with different beans injected inside?
I'm interested in ways how to achieve this in both Guice and Weld CDI.
So far I created multiple Guice modules and specify bind-to in it as I like. But I'm not completely sure if it is correct way. And this completely fails in CDI as there are no modules.
I thing that having multiple instances must be pretty common case or am I wrong?
The way you would do this with CDI is by setting up a producers for translator and source. It's the only way to control which implementations are used for injection at runtime. The implementation details may vary based on your exact needs but something like this should get you on the right track
#Produces
public Translator produceTranslator(#Dependent TranslatorA implA, #Dependent TranslatorB implB) {
return checkRuntimeCondition() ? implA : implB;
}
And the same for the source. That way when you inject Service, CDI'll call the producer method for each parameter and use a runtime condition to select the implementation. YMMV on the details, you may need to set up additional qualifiers to avoid ambiguity.

Depencency injection question

I have a question regarding dependency injection pattern.
My question is...
If I go for constructor injection, injecting the dependencies for my class, what I get is a "big" constructor with many params.
What if ie. I dont use some of the params in some methods?
Ie. I have a service that exposes many methods. And a constructor with 10 parameters (all dependencies). But not all the methods uses all the dependencies. Some method will use only one dependency, another will use 3 dependencies. But DI container will resolve them all even if non are used.
To me this is a performance penalty of using DI container. Is this true?
It seems your class is doing to much, that it does not comply to the S in SOLID (Single responsibility principle) , maybe you could split the class in multiple smaller classes with less dependencies. The fact that not all dependencies are used by all methods suggests this.
Normally the performance penalty of injecting many dependencies is low, but it depends on the framework you pick. Some will compile methods for this on the fly. You will have to test this. Many dependencies does indicate that your class is doing too much (like Ruben said), so you might want to take a look at that. If creation of an instance of a depedency that you often don't use causes performance problems, you might want to introduce a factory as dependency. I found that the use of factories can solve many problems regarding the use of dependency injection frameworks.
// Constructor
public Consumer(IContextFactory contextFactory)
{
this.contextFactory = contextFactory;
}
public void DoSomething()
{
var context = this.contextFactory.CreateNew();
try
{
// use context here
context.Commit();
}
finally
{
context.Dispose();
}
}
You can also hide some not-yet-needed dependencies behind lazy providers. For instance:
public DataSourceProvider implements Provider<DataSource> {
public DataSource get() {
return lazyGetDataSource();
}
}
The Provider interface is part of javax.inject package.
Actually you can't know which methods are used at runtime when you build your DI container. You would have to deal with that performance penalty or if you know that there are many cases where just a few dependencies are used, you could split your container into several small containers that have less dependencies that are injected.
As rube Says probabily you should review te design of your class to stick to SOLID principles.
Anyway if it is not really necessary I'm used to go for property setter dependency insteadof the constructor. It means that you can create a property for each dependecy you need. That helps also to test the class because you can inject only the dependency you need into the context of the test you are doing instead of stub out all the dependency even if you don't need it

Where to keep guice injectors?

What is your advice?
I found most suitable for me solution - keep injectors and modules in enumeration classes.
Advantages:
injectors and modules created once,
injectors can be used from different classes while running application (not only at bootstrap),
injectors kept in one place and can be easily found.
Example:
import static ru.package.Modules.*;
public enum Injectors {
FOO_INJECTOR(BarModule.module()),
FOO2_INJECTOR(FOO_INJECTOR.injector(),
Bar2Module.module(), FooModule.module());
private final Injector m_injector;
Injectors (Module... modules) {
m_injector = Guice.createInjector(modules);
}
Injectors (Injector parentInjector, Module... modules) {
m_injector = parentInjector.createChildInjector(modules);
}
public Injector injector() {
return m_injector;
}
}
You appear to be fundamentally misunderstanding how dependency injection works. If you are trying to use a reference to Injector anywhere in your code besides the place where you bootstrap the application, you're not using dependency injection, you're using it as a Service Locator instead. You're forced to prepare an Injector whenever you need to test a class and your classes do not make it clear in their constructors exactly what their dependencies are (since who knows what they'll get out of the Injector in some method if they have or can get a reference to it). Actually, using enum as you've described here is even worse than that: you cannot change the configuration at all, even for testing, because your modules are hardcoded into the enum.
With dependency injection, classes declare their dependencies only and allow the Injector, working transparently (after the initial call to get the root application object), to provide all those dependencies. This makes understanding, testing and changing functionality in your code relatively easy. Anyway, I'd suggest learning more about how DI and Guice are intended to be used... you really should not want to do this.
The bigger question is why?
There should be no need to keep the Injector around, because once the injection is done the Injector should be done and should disappear.
If, however, you really need the Injector, couldn't you simply:
#Inject
private Injector injector;
Is this application web based or is it standalone?

Resources