Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It seems to me like you need a scope for each instance of <code>RootObject</code> and all its dependencies.</p> <p>In Guice you can create a custom scope, say <code>@ObjectScoped</code>, like this:</p> <pre class="lang-java prettyprint-override"><code>@Target({ TYPE, METHOD }) @Retention(RUNTIME) @ScopeAnnotation public @interface ObjectScoped {} </code></pre> <p>Now just place <code>RootObject</code>, <code>A</code>, <code>B</code> and <code>D</code> into this scope:</p> <pre class="lang-java prettyprint-override"><code>@ObjectScoped public class RootObject { private A a; private B b; @Inject public RootObject(A a, B b) { this.a = a; this.b = b; } public A getA() { return a; } public B getB() { return b; } } @ObjectScoped public class A { private D d; @Inject public A(D d) { this.d = d; } public D getD() { return d; } } // The same for B and D </code></pre> <p>Now each <code>RootObject</code> has its own scope. You can implement this as a simple <code>HashMap</code>:</p> <pre class="lang-java prettyprint-override"><code>public class ObjectScope { private Map&lt;Key&lt;?&gt;,Object&gt; store = new HashMap&lt;Key&lt;?&gt;,Object&gt;(); @SuppressWarnings("unchecked") public &lt;T&gt; T get(Key&lt;T&gt; key) { return (T)store.get(key); } public &lt;T&gt; void set(Key&lt;T&gt; key, T instance) { store.put(key, instance); } } </code></pre> <p>To integrate these scopes with Guice you will need a <code>com.google.inject.Scope</code>-implementation which lets you switch the scopes and the corresponding wiring in your <code>Module</code>.</p> <pre class="lang-java prettyprint-override"><code>public class GuiceObjectScope implements Scope { // Make this a ThreadLocal for multithreading. private ObjectScope current = null; @Override public &lt;T&gt; Provider&lt;T&gt; scope(final Key&lt;T&gt; key, final Provider&lt;T&gt; unscoped) { return new Provider&lt;T&gt;() { @Override public T get() { // Lookup instance T instance = current.get(key); if (instance==null) { // Create instance instance = unscoped.get(); current.set(key, instance); } return instance; } }; } public void enter(ObjectScope scope) { current = scope; } public void leave() { current = null; } } public class ExampleModule extends AbstractModule { private GuiceObjectScope objectScope = new GuiceObjectScope(); @Override protected void configure() { bindScope(ObjectScoped.class, objectScope); // your bindings } public GuiceObjectScope getObjectScope() { return objectScope; } } </code></pre> <p>Initialize your program like this:</p> <pre class="lang-java prettyprint-override"><code>ExampleModule module = new ExampleModule(); Injector injector = Guice.createInjector(module); GuiceObjectScope objectScope = module.getObjectScope(); </code></pre> <p>Create the first instance of <code>RootObject</code> and its corresponding scope:</p> <pre class="lang-java prettyprint-override"><code>ObjectScope obj1 = new ObjectScope(); objectScope.enter(obj1); RootObject rootObject1 = injector.getInstance(RootObject.class); objectScope.leave(); </code></pre> <p>Just switch the scope for a second group of objects:</p> <pre class="lang-java prettyprint-override"><code>ObjectScope obj2 = new ObjectScope(); objectScope.enter(obj2); RootObject rootObject2 = injector.getInstance(RootObject.class); objectScope.leave(); </code></pre> <p>Test if your requirements are met:</p> <pre class="lang-java prettyprint-override"><code>assert rootObject1 != rootObject2; assert rootObject1.getA() != rootObject2.getA(); assert rootObject1.getA().getD() == rootObject1.getB().getD(); assert rootObject1.getA().getD() != rootObject2.getB().getD(); </code></pre> <p>To work with a group of objects just enter its scope and use the injector:</p> <pre class="lang-java prettyprint-override"><code>objectScope.enter(obj1); B b1 = injector.getInstance(B.class); objectScope.leave(); assert rootObject1.getB() == b1; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload