java - Guice injection with Builder pattern for client lib -
i new google guice , trying wrap head around how use particular scenario. building service client pretty complex , (i believe) requires builder pattern instantiated correctly. because client packaged own jar lib, guice handle di under hood. below greatly simplified version of code:
public interface myclient { public fizzresource getfizzresource(); public buzzresource getbuzzresource(); public fooresource getfooresource(); } public class myclientimpl implements myclient { // see below } public class getfizzcommand { // omitted brevity } public class getbuzzcommand { // omitted brevity } public class getfoocommand { // omitted brevity } public interface fizzresource { fizz getfizz(long fizzid); } public class fizzresourceimpl implements fizzresource { private getfizzcommand getfizzcommand; @override fizz getfizz(long fizzid) { return getfizzcommand.dogetfizz(fizzid); } } public interface buzzresource { buzz getbuzz(long buzzid); } public class buzzresourceimpl implements buzzresource { private getbuzzcommand getbuzzcommand; @override buzz getbuzz(long buzzid) { return getbuzzcommand.dogetbuzz(buzzid); } } public interface fooresource { foo getfoo(long fooid); } public class fooresourceimpl implements fooresource { private getfoocommand getfoocommand; @override foo getfoo(long fooid) { return getfoocommand.dogetfoo(fooid); } }
so can see hierarchy/dep graph follows:
myclient
should injected*resourceimpl
s- each
*resourceimpl
should injected*command
instance
the intended use case make building myclient
impl easy as:
myclient myclient = myclientimpl.builder("myservice.example.org", 8080l, getwidget()) .withauth("user", "password") .withhttps() .withfailurestrategy(somefailurestrategy) // ...etc. .build();
so here's best attempt @ myclientimpl
, internal builder , guice module:
public class baseclient { private string uri; private long port; private widget widget; // ctor, getters , setters } public class myclientimpl extends baseclient implements myclient { @inject private fizzresource fizzresource; @inject private buzzresource buzzresource; @inject private fooresource fooresource public myclientimpl(string uri, long port, widget widget) { super(uri, port, widget); } public static class builder { private string uri; private long port; private widget widget; builder(string uri, long port, widget widget) { super(); seturi(uri); setport(port); setwidget(widget); } // lots of methods on builder setting lots of myclient-specific properties // have omitted here brevity. myclient build() { injector injector = guice.createinjector(new myclientmodule(this)); return injector.getinstance(myclient.class); } } } public class myclientmodule extends abstractmodule { private myclientimpl.builder builder; public myclientmodule(myclientimpl.builder builder) { super(); setbuilder(builder); } @override protected void configure() { myclientimpl myclientimpl = new myclientimpl(builder.geturi(), builder.getport(), builder.getwidget()); bind(myclient.class).toinstance(myclientimpl); } }
but life of me, can't see how/where to:
- bind
*command
s*resourceimpl
s; and - bind
*resourceimpl
smyclientimpl
instance
any ideas?
it's not clear entirely you're trying accomplish injections. may confusing matter further making builders , other aspects of design. suggest strip code down sscce functions not include injection, , increment design injecting, example, single field. right code shows trimmed down skeleton of complex design injections don't make sense, , there no way run code , see happens. guice operates @ runtime, it's essential see main
method see application code does.
below follows simple example of describe above.
an interface 2 different impls:
public interface service { void useservice(); } public class fooservice implements service { public void useservice() { system.out.println("foo service used"); } } public class barservice implements service { public void useservice() { system.out.println("bar service used"); } }
a vanilla (non-guice) user of interface:
public class serviceuser { service service = new fooservice(); // change impl used here public static void main(string[] args) { new serviceuser().service.useservice(); } }
a guicified user of interface:
public class serviceuserguicified { @inject service service; public static void main(string[] args) { injector injector = guice.createinjector(new fooservicemodule()); serviceuserguicified user = injector.getinstance(serviceuserguicified.class); user.service.useservice(); } } public class fooservicemodule extends abstractmodule { @override protected void configure() { bind(service.class).to(fooservice.class); } }
in guicified version, impl definition coded in guice module rather in runtime code. thing runtime code includes usage of module when creating injector. make new module bar service , use create injector instead, or change binding in primary service module.
once understand happening above, should able solve issues in own code repeating concepts on every instance want injected guice.
Comments
Post a Comment