Customise the creation of a gin managed object or creating two different instances of the same class - gwt

I want to be able to create two instances of the same class and have them be injected with different properties and then have those two objects injected into two specific locations in my application.
Currently I have a method in my ClientModule...
#Provides
#Named("bean1")
public MainBean getMainBean() {
MainBean mainBean = new MainBean(new SecondaryBean());
return mainBean;
}
And then in my presenters etc I do the following:
public MyPresenter(final EventBus eventBus, final MyView view,
#Named("bean1") MainBean bean, TitleSetupData data) {
super(eventBus, view);
this.bean1 = bean1;
}
And it works great. Based on the #Named annotation corresponding I get the correct bean.
However, this approach has a weakness in that I need to create and inject all the dependencies of MainBean in the #Provides method.
So any #Inject annotations of SecondaryBean are not honoured for example.
One thing I could do is pass into the getMainBean method any relevant dependencies but I'm wondering if there might be another more elegant or better solution.
Anyone got any ideas?

I came across the same problem.
What you are looking for is #Assisted Inject, where some of the constructor parameters are injected, and some are passed as arguments when you instantiate your object.
You can find a full example at this blog post which helped me getting started.

Related

Inject in Dagger an object with needs activity to be created

Greeting all!
Please help me to figure out if the scenario, I need to cope with, which meets the Dagger concepts.
I have to inject a class into my Activity which needs this activity to be created. The only way comes to my mind is to add the activity to the Model and use it in the object Provides method. does it sound like a normal usage scenario.
#Module
public class SampleDiModule {
private Activity activity;
public SampleDiModule(Activity activity){
this.activity = activity;
}
#Provides
#ModuleScope
public InjectedObject provideInjectedObject(){
return new InjectedObject.createForAcivity(activity)
}
}
My intention to inject an activity presenter, the presenter depends on a object which could be created only by the object factory in the following way
public MyPresentor(InjectedObject object){
}
InjectedObject object = InjectedObjectFactory.forActivity(this)
Thanks
Ok, there are multiple ways to achieve this.
Two of them are on top of my mind.
First, using Dagger scopes. You can create #Activity scope which will manage objects that have life bound to life of particular activities. When creating dagger module that is scoped to Activity, you can pass an activity reference as constructor parameter, and then use it. Something like this (in pseudocode):
class ActivityScopedModule {
ActivityScopedModule(Activity: activity) {
this.activity = activity;
}
CustomObject provideCustomObject() {
return new CustomObject(this.activity);
}
}
Important thing is that modules that are scoped to activity must be instantiated from Activity.onCreate() Here you can find more about creating dagger scopes: http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/ Or in this three-part series: https://android.jlelse.eu/dagger-2-part-i-basic-principles-graph-dependencies-scopes-3dfd032ccd82
Another approach, the easier one, would be to, instead of using static InjectedObjectFactory.forActivity(this), to make it as non-static class InjectedObjectFactory, make it's instance in dagger module as new InjectedObjectFactory() and then from activity you call myInjectedObjectFactory.forActivity(this) and pass it to presenter.

Dagger 2, scopes + annotation

I never worked with such a confusing DI-framework like dagger! - However, I try to wrap my head around it.
I have two scopes: ActivityScope and FragmentScope
On some of the samples provided StatisticsFragment.java you see e.g. the fragment annotated with the scope
#ActivityScoped
public class StatisticsFragment extends DaggerFragment implements
StatisticsContract.View {
...
}
Question 1:
Is this just documentation or not? In my app it makes no difference if I annotate the concrete fragment or not.
Question 2: Where in the generated code can I see which scope is used? My fragment injects a Presenter and an AuthProvider. The AuthProvider is annotated with Singleton (in AppModule), the Presenter is defined in UIModule -> LoginModule
looks like this:
UIModule.java:
#Module(includes = AndroidSupportInjectionModule.class)
public abstract class UIModule {
#ActivityScope
#ContributesAndroidInjector(modules = LoginModule.class)
abstract LoginActivity loginActivity();
#ChildFragmentScope
#ContributesAndroidInjector(modules = LoginModule.class)
abstract LoginFragment loginFragment();
#Binds
//#ChildFragmentScope
public abstract LoginContract.View loginView(final LoginFragment fragment);
}
LoginModule.java
#Module
public abstract class LoginModule {
#Provides
//#ChildFragmentScope
static LoginContract.Presenter provideLoginPresenter(final LoginContract.View view, final BaseStore store) {
return new LoginPresenter(view,store);
}
}
LoginFragemt.java
public class LoginFragment extends DaggerFragment {
#Inject
LoginContract.Presenter presenter;
#Inject
Provider<MyAuthClass> myAuthClass;
...
}
presenter is created every time the Fragment gets created, myAuthClass gets created only once and is singleton.
Perfect - but I have no idea HOW this works!!!
DaggerFragment#onAttach must somehow know that Presenter is a "local" singleton and MyAuthClass is a global-singleton ...
Scope is one of two ways you can tell Dagger to always bind the same object, rather than returning a newly-created one on each injection request. (The other way is the manual way: Just return the same object in a #Provides method.)
First, a scope overview: Let's say you have a component, FooComponent, which has a #FooScope annotation. You define a subcomponent, BarComponent, which has a #BarScope annotation. That means that using a single FooComponent instance, you can create as many BarComponent instances as you want.
#FooScoped
#Component(modules = /*...*/)
public interface FooComponent {
BarComponent createBarComponent(/* ... */); // Subcomponent factory method
YourObject1 getYourObject1(); // no scope
YourObject2 getYourObject2(); // FooScoped
}
#BarScoped
#Subcomponent(modules = /*...*/)
public interface BarComponent {
YourObject3 getYourObject3(); // no scope
YourObject4 getYourObject4(); // BarScoped
YourObject5 getYourObject5(); // FooScoped
}
When you call fooComponent.getYourObject1(), YourObject1 is unscoped, so Dagger does its default: create a brand new one. When you call fooComponent.getYourObject2(), though, if you've configured that YourObject2 to be #FooScoped, Dagger will return exactly one instance for the entire lifetime of that FooComponent. Of course, you could create two FooComponent instances, but you'll never see multiple instances of a #FooScoped object from the same #FooScoped component (FooComponent).
Now onto BarComponent: getYourObject3() is unscoped, so it returns a new instance every time; getYourObject4() is #BarScoped, so it returns a new instance for each instance of BarComponent; and getYourObject5() is #FooScoped, so you'll get the same instance along the instance of FooComponent from which the BarComponent was created.
Now to your questions:
Question 1: Is this just documentation or not? In my app it makes no difference if I annotate the concrete fragment or not.
In classes that have an #Inject-annotated constructor like StatisticsFragment does, adding a scope annotation is not simply documentation: Without the scope annotation, any requests to inject a StatisticsFragment will generate a brand new one. If you only expect there to be a single instance of StatisticsFragment per Activity, this may be surprising behavior, but it might be hard to notice the difference.
However, adding an #Inject annotation to a Fragment may be something of a controversial move, because the Android infrastructure is able to create and destroy Fragment instances itself. The object that Android recreates will not the scoped one, and it will have its members reinjected onAttach due to DaggerFragment's superclass behavior. I think a better practice is to drop the #Inject annotation from the constructor and stick with field injection for your Fragment. At that point you can drop the scope, because Dagger will never create your Fragment, so it'll never decide whether to create a new one or return an existing one.
Question 2: Where in the generated code can I see which scope is used? My fragment injects a Presenter and an AuthProvider. The AuthProvider is annotated with Singleton (in AppModule), the Presenter is defined in UIModule -> LoginModule
The generated code and scoping is always generated in the Component; subcomponents will have their implementations generated as an inner class of the Component. For each scoped binding, there will be a place in the initialize method where the Provider (e.g. AuthProvider) is wrapped in an instance of DoubleCheck that manages the double-checked locking for singleton components. If nobody asks Dagger to create an object (like StatisticsFragment), Dagger can determine the lack of component factory methods or injections in the graph, and can avoid adding any code generation for it at all—which might be why you're not seeing any.

Using JasperReports with datasources which rely on CDI

I have some classes which use CDI injected beans in their getters, e.g.:
class MyBean() {
#Inject
private TranslationBean translationBean;
private String chosenValue;
public void setChosenValue(String c) { chosenValue = c;}
public String getChosenValue() {
return translationBean.getTranslatedValue(chosenValue);
}
}
The underlying chosenValue is loaded from and persisted into a database.
Now I want to create a JasperReport generated PDF with such beans as DataSource. I call:
JasperFillManager.fillReport("myFile.jasper", new HashMap<String, Object>(), new JRBeanCollectionDataSource(Arrays.asList(myBean));
Obviously, the error message from Weld will eventually be that no context is active.
I now see two possibilities:
create a wrapping class for MyBean especially for JasperReports in which all needed fields are filled with actual data and no CDI dependencies are needed. Problem would be: a LOT of coding with a lot of boilerplate and repeating code.
Somehow manage to wrap a context around the call to the JasperFillManager so it runs within an/the current active CDI context.
Would the second option be possible? Is there any other, nicer way than one of the proposed ones?
You're probably looking at creating a new scope, if its possible to wrap all the JasperStuff. Take a look at the Seam Reports stuff in https://github.com/seam/reports, it may be of some help or inspiration.

GIN #Inject on variable for Rpc Services

I'm a bit lost with the use of Inject on variable.
I got this code working :
private XXServiceAsync xxServiceAsync;
#Inject
protected IndexViewImpl(EventBus eventBus, XXServiceAsync tableManagementServiceAsync) {
super(eventBus, mapper);
this.xxServiceAsync = xxServiceAsync;
initializeWidgets();
}
With this code, I can call my RPC service wherever I need in the class (On click ...)
I would like to clear a bit the code by injecting direcly in the variable ; doing so :
#Inject
private XXServiceAsync xxServiceAsync;
protected IndexViewImpl(EventBus eventBus) {
super(eventBus, mapper);
initializeWidgets();
}
This always keep the Service to NULL.
Am I doing something wrong ? Is the GIN magic with rpc services meant to be done otherwise?
Thanks!
It is still null at that point, because Gin (and Guice, and other frameworks like this) cannot assign the fields until the constructor has finished running.
Consider how this would look if you were manually wiring the code (remember that Gin/Guice will cheat a little to assign private fields, call non-visible methods):
MyObject obj = new MyObject();//initializeWidgets() runs, too early!
obj.xxServiceAsync = GWT.create(xxService.class);
If you need something in the constructor, pass it into the constructor. If you wont need it right away (such as until asWidget() is called), then a field or setter annotated with #Inject can be helpful.
If you have field level injection you can use an empty #Inject method to do your post-inject initialization. The no-arg injected method will be run after field injections on the class are complete.
#Inject void initialize(){
...
initializeWidgets()
}
Edit: I previously stated that it was run after method injection as well, but testing shows that this is not always the case.

Best practice in dependency injection

This is a question about how best to do DI, so it's not tied to any particular DI/IoC framework because, well, framework should be chosen based on pattern and practice rather than the other way around, no?
I'm doing a project where repository has to be injected into services, a service may require multiple repositories and I'm curious about the pros and cons between following approaches:
Inject repositories in service constructor
public class SomeService : ISomeService
{
private IRepository1 repository1;
private IRepository2 repository2;
public SomeService(IRepository1 repository1, IRepository2 repository2)
{
this.repository1 = repository1;
this.repository2 = repository2;
}
public void DoThis()
{
//Do something with repository1
}
public void DoThat()
{
//Do something with both repository1 and repository2
}
}
Inject a custom context class that include everything any service may need but lazy instantiated (the IServiceContext will be a protected field in BaseService)
public class SomeService : BaseService, ISomeService
{
public SomeService(IServiceContext serviceContext)
{
this.serviceContext= serviceContext;
}
public void DoThis()
{
//Do something with serviceContext.repository1
}
public void DoThat()
{
//Do something with both serviceContext.repository1 and serviceContext.repository2
}
}
Inject into methods that need them only
public class SomeService : ISomeService
{
public void DoThis(IRepository1 repository1)
{
//Do something with repository1
}
public void DoThat(IRepository1 repository1, IRepository2 repository2)
{
//Do something with both repository1 and repository2
}
}
Some pointers would be appreciated, moreover what're the aspects that I should consider in evaluating alternative like these?
The preferred way of injecting dependencies is Constructor Injection.
Method Injection is less ideal, because this will quickly result in having to pass around many dependencies from service to service and it will cause implementation details (the dependencies) to leak through the API (your method).
Both options 1 and 2 do Constructor Injection, which is good. If you find yourself having to inject too many dependencies in a constructor, there is something wrong. Either you are violating the Single Responsibility Principle, or you are missing some sort of aggregate service, and this is what you are doing in option 2.
In your case however, your IServiceContext aggregate service is grouping multiple repositories together. Many repositories behind one class smells like a unit of work to me. Just add a Commit method to the IServiceContext and you will surely have a unit of work. Think about it: don't you want to inject an IUnitOfWork into your service?
The first option seems to be the most natural from a DI perpective. The service class requires both repositories to perform its function, so making them required in order to construct an instance makes sense semantically (and practically).
The second option sounds a bit like Service Location, which is generally considered an anti-pattern (see http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx). In a nutshell, it creates implicit dependencies, where explicit dependencies are always preferred.
I would do either constructor based injection or property based injection. I would not pass in a context that contains the dependencies unless that context is serving some other purpose.
I prefer constructor based injection for required dependencies, as it makes it super easy for the object creation to blow up if something is missing. I got that from here. If you are going to verify that your dependencies are met, then you have to do it with constructor based injection, since there is no way to tell which setter is the last setter to be fired.