Hi Google Guice community. Can I make a suggestion, would it possible to have a debug mode, with a warning if a mapping which is declared as Singleton is created more than once as in this example? A class which implements multiple interfaces isn't that unusual. And I don't belive Singletons are in themselves bad, just perhaps the old Singleton Design pattern isn't the best.
Thanks Martin On 18 Jun., 20:28, Marty <[email protected]> wrote: > Thank you so much Fred. > > So basically the topic of my email was wrong, it had nothing to do > with the legacy use of my SingletonFactory + with additional calls to > injector.getInstance, > my problem was how google guice dealt with 2 interfaces being bound to > the same implementation and creating a singleton FOR EACH INTERFACE. > with that one line of code, my problems are solved. > > Thanks to you discussing this through with me, due to now > understanding the problem, I've now fixed another (harmless bug) > occurance of this bug in my code. > > How cool is Google guice (and google too). > > Thanks > > Martin. > > On 18 Jun., 15:19, Fred Faber <[email protected]> wrote: > > > > > Correct. This allows folks who want the same implementation class to be > > used as the binding for more than one Key to be scoped independently for > > each Key. > > > What you would have done in your original module to prevent this is to add > > an explicit binding for SingletonManagerImpl: > > > bind(SingletonManagerImpl.class) > > .in(Singleton.class); > > > The linked bindings of SingletonManager => SingletonManagerImpl > > and SingleTablePanelMgr => SingletonManagerImpl would then have resolved > > down to the explicit binding of SingletonManagerImpl, which would have had > > one singleton instance in the app. > > > On Sat, Jun 18, 2011 at 8:45 AM, Marty < > > > [email protected]> wrote: > > > Hi Fred. > > > > Well if that is true, then I should never have had a problem.... > > > In my factory constructor, was using injector.getInstance(Singleton) > > > and since my Singleton class was scoped as Singleton (sensibly), it > > > should have always returned the same instance as something generated > > > indirectly in the object tree of another getInstance call, according > > > to what you say, regardless of whether the Singleton instance was > > > obtained in the initial object tree creation or via a seperate call to > > > injector.getInstance there should always be just 1 instance. > > > > ahhh and now I light goes on....I actually had two interfaces, which > > > the Singlton class was implementing (its a rather large difficult to > > > test class, I want to break it up later). > > > perhaps I had a singleton class created for each interface, even > > > though the class was the same? > > > > old module: > > > //creates 2 instances of SingletonManagerImpl because only the > > > interface is declared to be Singleton not the implementation??? > > > > bind(SingletonManager.class).to(SingletonManagerImpl.class).in(Scopes.SINGLETON); > > > > bind(SingleTablePanelMgr.class).to(SingletonManagerImpl.class).in(Scopes.SINGLETON); > > > > my new module: > > > > bind(SingletonManager.class).toInstance(SingletonManagerFactory.getInstance()); > > > > bind(SingleTablePanelMgr.class).toInstance(SingletonManagerFactory.getInstance()); > > > > if this is true, this could create quite a few nasty side affects, > > > where classes I thought were Singletons, aren't because they implement > > > multiple interfaces and declared in multiple binds. > > > > Thanks > > > > Martin > > > > On 17 Jun., 23:21, Fred Faber <[email protected]> wrote: > > > > And that's the thing: Guice scopes the objects it creates, so repeated > > > > calls to getInstance() on an object scoped as a singleton returns the > > > same > > > > instance. This instance is also used to assign @Inject-annotated > > > variables. > > > > > Does that make sense? > > > > > On Fri, Jun 17, 2011 at 5:19 PM, Marty < > > > > > [email protected]> wrote: > > > > > For 2. there was never a "new" but rather > > > > > injector.getInstance(SingletonManager.class), so it was also being > > > > > created by Guice, but by 2 seperate calls to getInstance. > > > > > Should I try to create a test case to explain the "problem" in greater > > > > > detail? > > > > > > On 17 Jun., 23:08, Fred Faber <[email protected]> wrote: > > > > > > In the first model your two instances came from: > > > > > > > 1) Guice, creating its version of the singleton class > > > > > > 2) The logic within the static factory method of the class > > > > > > > In the injectMembers model, you only have Guice creating the > > > instances > > > > > that > > > > > > are injected (I presume), meaning there's nothing else actually > > > > > > doing > > > a > > > > > > "new" on those classes. > > > > > > > Fred > > > > > > > On Fri, Jun 17, 2011 at 3:50 PM, Marty < > > > > > > > [email protected]> wrote: > > > > > > > Hi Fred, thanks for your quick reply. > > > > > > > > That worked like a charm. > > > > > > > For a moment I had a wonderful circle, where the SingletonFactory > > > > > > > called its getInstance() (SingletonManager) -> getInjector -> new > > > > > > > Module() -> getInstance(), so I had to revert to an older > > > constructor > > > > > > > and then "post inject" the other variables with > > > > > > > injectMembers(instance). > > > > > > > > Now I could swear, I should have this problem later as well, (due > > > to > > > > > > > injectMembers), but it seems to only create 1 instance of the > > > > > > > code, > > > > > > > which is later reused in @Inject. Shouldn't the members injected > > > via > > > > > > > injectMembers (which have the scope singleton) also have 2 > > > instances > > > > > > > as I had previously? > > > > > > > > Thanks > > > > > > > > Martin > > > > > > > > On 17 Jun., 20:58, Fred Faber <[email protected]> wrote: > > > > > > > > The easy solution is to bind your SingletonManager to the > > > instance > > > > > that > > > > > > > your > > > > > > > > legacy code returns: > > > > > > > > > bind(SingletonManager.class) > > > > > > > > .toInstance(SingletonManager.getInstance()); > > > > > > > > > then the inejcted instance will be the same as the one your > > > legacy > > > > > code > > > > > > > > uses. > > > > > > > > > Fred > > > > > > > > > On Fri, Jun 17, 2011 at 2:51 PM, Marty < > > > > > > > > > [email protected]> wrote: > > > > > > > > > Hi Google guice users. > > > > > > > > > > I have a rather large Legacy Code which previously was very > > > > > > > > > dependendent on a Singleton design pattern. Basically > > > everywhere I > > > > > > > > > was dependant on SingletonManager, which gave me access to > > > global > > > > > > > > > state, etc, while making it impossible to test parts of the > > > code > > > > > > > > > independantly. > > > > > > > > > > I recently introduced Google Guice to the code and have been > > > > > > > > > attempting to seperate dependancies in the code, with some > > > success > > > > > :) > > > > > > > > > > One thing that shocked me today, my code starts and seems to > > > work , > > > > > by > > > > > > > > > asking the Injector to provide a Frame, I get one > > > SingletonManager > > > > > > > > > from the @Inject annotations in my Frame and another when I > > > > > previously > > > > > > > > > call the same injector and request a SingletonManager > > > > > > > > > > ///from my Module: > > > > bind(SingletonManager.class).to(SingletonManagerImpl.class).in(Scopes.SINGLETON); > > > > > > > > > > ///my main method: > > > > > > > > > SingletonManager mgr = > > > > SingletonManagerFactory.getInjector().getInstance(MainFrame.class); > > > > > > > > > //do some legacy stuff > > > > > > > > > > //now initialise the GUI (and the main Object tree). > > > > > > > > > MainFrame mainFrame; > > > > > > > > > if (CsConstants.USE_GOOGLE_GUICE_INJECTION == true) { > > > > > > > > > mainFrame = > > > > SingletonManagerFactory.getInjector().getInstance(MainFrame.class); > > > > > > > > > } else { > > > > > > > > > mainFrame = new MainFrameImpl(); > > > > > > > > > } > > > > > > > > > //use the frame (pack, etc).... > > > > > > > > > > ///a class annoted with @Inject > > > > > > > > > public class AClass implements XXX { > > > > > > > > > private SingletonManager mgr; > > > > > > > > > > @Inject > > > > > > > > > public AClass(SingletonManager mgr) { > > > > > > > > > this.mgr = mgr; > > > > > > > > > } > > > > > > > > > } > > > > > > > > > > ///code when I need an Instance of the SingletonManager class > > > for > > > > > > > > > Legacy code > > > > > > > > > public static SingletonManager getInstance() > > > > > > > > > { > > > > > > > > > if(instance==null) > > > > > > > > > { > > > > > > > > > //returns aa DIFFERENT instance of this > > > > > > > > > instance = > > > > > > > > > getInjector().getInstance(SingletonManager.class); > > > > > > > > > } > > > > > > > > > return instance; > > > > > > > > > } > > > > > > > > > > Now when the MainFrame is created Google Guice goes through > > > > > > > > > the > > > > > code > > > > > > > > > and creates all my classes. It works great:) > > > > > > > > > > Now the problem is, because my code base is rather large, I > > > don't > > > > > have > > > > > > > > > time to change all the code to injection. In some places this > > > will > > > > > be > > > > > > > > > very difficult e.g. classes initialized by the Netbeans GUI > > > > > designer > > > > > > > > > (not a good choice for Dependency Injection). So in these > > > places > > > > > where > > > > > > > > > due to time or difficulty I sometimes use my old Singleton > > > class. > > > > > Now > > > > > > > > > here is my problem, I recently discovered that I get 2 > > > instances of > > > > > a > > > > > > > > > class which is scoped as Singleton. > > > > > > > > > > 1. In the initial object tree creation. > > > > > > > > > 2. When I call SingletonManagerFactory.getInstance() > > > > > > > > > > Am I stupid? is this a bug? what should I do differently? Do > > > you > > > > > need > > > > > > > > > a complete test case? > > > > > > > > > > I swear, due to my Singleton I only have 1 injector! > > > > > > > > > > Thanks > > > > > > > > > > Martin > > > > > > > > > > -- > > > > > > > > > You received this message because you are subscribed to the > > > Google > > ... > > Erfahren Sie mehr » -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
