I have an UI component that will be used in several UI module in an application.
I would like to annotate the UI component that to be injected into several other classes in one UI module to be a singleton, but not a singleton across the whole application. So that for each UI module use the UI component, one and only one of the UI component instance is used.
I couldn't find a straight solution for this from the Guice document. So i think maybe I can use annotation to distinguish those instance?
Say in Module A, I annotate all the injection of the UI component with Named("ModuleA"); and in Module B, with Named("ModulaB"). and in the configuration, i tried to use something like:
this.bind(UIComponentA.class)
.annotatedWith(Names.named("ModulaA"))
.to(UIComponentAImpl.class).in(Singleton.class);
this.bind(UIComponentA.class)
.annotatedWith(Names.named("ModulaB"))
.to(UIComponentAImpl.class).in(Singleton.class);
Because UICompoenetAImpl also need to be injected, so I couldn't simply create the instance there. Totally not sure if this works.
And I'm wondering what's the standard way to accomplish this?
One other option might be to use a child injector for each module.
This would allow you to bind a difference instance of UIComponentA in each module. Bind them in the child injector rather than the parent. You would then need to make sure that all of your module's dependencies are built from the right child injector, probably by making sure the root of each module is loaded from the right place.
Because UICompoenetAImpl also need to be injected, so I couldn't simply create the instance there.
I think you can just create UIComponentAImpl there and bind toInstance. When you do so - other beans will be injected in UIComponentAImpl. Please see my example here.
Related
I am trying out the toothpick DI library and I seem to miss something crucial.
I created the following test project on github where I tried to make a smallest possible use case for my understanding issue.
There you will find the ApplicationModule where I try to inject everything I need in my "root" module. As you can see there, I have twice scope.installModules(module) because my PlainPojo depends on the Application instance. If I do not do the first installModule call, I have no application instance in the scope. I could, as mentioned in the comment, pass the application instance as a parameter but I thought that I can remove them when I use DI?
The second class that causes troubles is the SimpleTest class. If I do not call the inject() method in the constructor, the PlainPojo member will not be injected. I also tried to use a third time the installModules() in the ApplicationModule after binding the PlainPojo but that does not help.
Am I so wrong to assume that an #Inject on a member is enough to automatically inject it when it is available in the scope and that the order of binding is enough to make previous bindings available without installing in between (like done in ApplicationModule)?
If I can provide anything more to make my issue(s) understandable please leave a comment.
Thanks in advance!
Toothpick can only inject dependencies automatically when it creates the instance of the depended object itself (e.g it is annotated with #Singleton or there is a direct binding for the class).
Otherwise you have to manually call Toothpick.inject, just like you do in SimpleTest. There is no way for TP to know when you call the constructor of PlainPojo.
You could just use
module.bind(PlainPojo.class);
module.bind(SimpleTest.class);
and maybe scope them as singletons if needed.
So I've been playing around with Dagger2 with Android for a little bit and I'm starting to wrap my head around how dependencies are injected. I understand that for building components, one of the more common places for this code is in your Application class. This way I can call getApplication().getMyComponent() from my various activities, and inject the relevant fields into the Activity.
However, let's say I have a POJO and I want to inject another POJO into this (say a Service object with a DAO object inside it) and I'm injecting it using POJOComponent. Now, I can't build this in the Application class like before because I'm no longer injecting into an Activity (i.e. no access to 'getApplication()'), so my question is this; should I just build the component in the Service object and then inject the DAO? This doesn't seem correct to me, since if I wanted to inject the DAO into a different object/class, I would need to build my component in that object as well.
Surely I should just have to build my component once and use to inject the DAO into different objects/classes? One way I could think of was using static methods in the Application class but this feels like a hack. Any guidance would be appreciated!
Never use static methods or variable, if you can avoid it. There is most likely a better way.
If you have a android.app.Service, that service itself is/has a Context and you can just as easily get the Application and/or create a new component with that service context.
Then you can just inject it as you would with activities, or fragments.
If you are talking about Service as some sort of business logic class, then you have access to the constructor. In this case you can—and should—make use of Constructor injection.
If you need MyDao, put it in the constructor. Don't get into the habit, that each class grabs and takes the dependencies it needs. If something wants to use your service, it needs to supply it with the dao.
Wherever you use your Service class, there you should think about how to provide those dependencies. This will most likely be in an Activity, Application, Fragment, or Service again, where—as already pointed out above—you'll have access to the application and component again.
I would like some suggestions and feedback on the best way to structure dependency injection for a system with the structure described below. I'm using Guice and thus would prefer solutions centered around it's annotation-based declarations, not XML-heavy Spring-style configuration.
Consider a set of similar objects, Ball, Box, and Tube, each dependent on a Logger, supplied via the constructor. (This might not be important, but all four classes happen to be singletons --- of the application, not Gang-of-Four, variety.)
A ToyChest class is responsible for creating and managing the three shape objects. ToyChest itself is not dependent on Logger, aside from creating the shape objects which are.
The ToyChest class is instantiated as an application singleton in a Main class.
I'm confused about the best way to construct the shapes in ToyChest. I either (1) need access to a Guice Injector instance already attached to a Module binding Logger to an implementation or (2) need to create a new Injector attached to the right Module.
(1) is accomplished by adding an #Inject Injector injectorfield to ToyChest, but this feels weird because ToyChest doesn't actually have any direct dependencies --- only those of the children it instantiates.
For (2), I'm not sure how to pass in the appropriate Module.
Am I on the right track? Is there a better way to structure this?
The answers to this question mention passing in a Provider instead of using the Injector directly, but I'm not sure how that is supposed to work.
EDIT:
Perhaps a more simple question is: when using Guice, where is the proper place to construct the shapes objects? ToyChest will do some configuration with them, but I suppose they could be constructed elsewhere. ToyChest (as the container managing them), and not Main, just seems to me like the appropriate place to construct them.
A proper way is to have guice construct your dependencies. That is create and configure.
In your situation you should have an injector constructed in the Main. From the injector you get ToyChest. When you obtain ToyChest through the injector its managed by guice and you can depend on it to supply all dependencies properly configured.
In your case you can inject Provider<Ball>, Provider<Box>, etc. in ToyChest and when needed just retrieve instance from the provider. ToyChest is not responsible for constructing the instance, just to use it. You can also check MapBinder if you have a plugin architecture.
So far everything is managed by guice, so the shapes can have their logger injected without the using class knowing about it.
If you have some runtime parameters that you want to pass to the newly created shape instances, you can use AssistedInject.
Just a hint: you are not required to use constructor injection, you can have injection on field or setter, which simplifies the constructor.
Say I have a database layer, with DTO's for each table, and a factory that returns the DTO's for each table.
As long as I build to interfaces, I can re-implement the db layer and then just change my app-config.xml to use another implementation.
Now, is it possible for me to have this new implementation in another .jar file?
The goal is to allow for someone else to run this spring mvc application, drop their own implementation and change the app-config.xml file so that it now uses their library to re-implement a module.
Is this possible? How exactly do I go about this?
Is this possible?
Yes.
How exactly do I go about this?
Well the straight-forward approach would be to expose a setter for the DTOFactory instance in some bean that you have previously declared in your "app-config.xml" file. Then instantiate and inject the required DTOFactory bean via the corresponding property. To use an alternative factory, just change the classname in the bean.
The approach above assumes that your application currently use a shared instance of the (existing) DTOFactory class.
Say I have a ClassWithManyDependencies. I want to write a Guice Provider for this class, in order to create a fresh instance of the class several times in my program (another class will depend on this Provider and use it at several points to create new instances).
One way to achieve this is by having the Provider depend on all the dependencies of ClassWithManyDependencies. This is quite ugly.
Is there a better way to achieve this?
Note - I certainly don't want the Provider to depend on the injector. Another option I considered is having ClassWithManyDependencies and ClassWithManyDependenciesProvider extend the same base class, but it's butt ugly.
As mentioned on the mailing list, anywhere you can inject ClassWithManyDependencies you can simply inject Provider<ClassWithManyDependencies> instead, no need to write anything special yourself. Guice does this for you.
You shouldn't have to write a provider except to integrate with other frameworks.
Just DON'T bind your ClassWithManyDependencies in scope SINGLETON and in the class that wants to build many instances, instead of having a ClassWithManyDependencies instance injected you have a Provider injected. (Guice can do that for free for every binded class)
On this provider you can just call get(), if not in scope SINGLETON it makes a fresh new instance each time.
Now if you are in the tricky case that ClassWithManyDependencies relies both on some GUICE IOC and on some constructor parameters, then you shall go for Assisted Injections