Assisted Injection and AutoFactory

1,426 views
Skip to first unread message

Christian Edward Gruber

unread,
Apr 21, 2014, 12:59:49 PM4/21/14
to dagger-...@googlegroups.com
Hey folks,

After a lot of side discussion last year (which I apologize never hit the list), the core dagger team concluded that assisted-injection was, itself, not a core feature of Dagger.  But the idea is sound, and it launched the early attempts to put together something more "Daggery", taking in mind the discussion about assisted-injection on this mailing list.  

The result was AutoFactory (https://github.com/google/auto/tree/master/factory) which has been released to maven in an early beta form.  That discussion, and dagger's approach in general, sparked a pretty consistent shift in how the core libraries team at google thinks about APIs, and so a more general project http://github.com/google/auto was created to house AutoFactory, but also other "boiler-plate" generators, such as for simple value objects (AutoValue), java.util.ServiceLoader configuration (AutoService), and possibly more.

Please feel free to try out AutoFactory.  At present, it generates a factory for your type annotated with @Provided and mingles injected state and call-stack state to assemble your factory-created type.  More or less

@AutoFactory
class Foo {
  private final Bar bar;
  private final Baz baz;
  Foo(@Provided Bar bar, Baz baz) {
     ...
  }
}

gets you:

@Generated(value = "com.google.autofactory.AutoFactoryProcessor")
final class FooFactory {
  private final Provider<Bar> providedBarProvider;

  @Inject SomeClassFactory(Provider<Bar> providedBarProvider) {
    this. providedBarProvider = providedBarProvider;
  }

  Foo create(Baz baz) {
    return new Foo(providedBarProvider.get(), baz);
  }
}

Some options available include

@AutoFactory(
    className="CustomFactoryName", 
    implementing = { MyInterface.class, MyOtherInterface.class },
    extending = MyFactorySupertype.class)
class ...


Anyway - please play around with it.  There is some more work to be done on it, but I'd like to drive as much future development on AutoFactory from real user needs.  So please do file issues, feature requests, etc.   Please note we have a lot of documentation to do on AutoFactory.  You are warned. :)

Christian.

P.S.  A small plug for AutoValue (https://github.com/google/auto/tree/master/factory) which makes small immutable value type creation trivial with the same inspectability and debuggability that we get from dagger-generated adapters. (Examples are in the docs which have gotten a little more love than AutoFactory docs.

Pierre-Yves Ricau

unread,
May 2, 2014, 3:14:17 AM5/2/14
to dagger-...@googlegroups.com
Hi,

I just tried adding AutoFactory in Square Register. We have a few places with factories that are almost 1:1 mapping of what AutoFactory generates, except we wrote them manually :) .

I had to do a few maven trickeries: exclusions (dagger and AutoFactory don't depend on the same javawriter and guava), also downgrade dagger version. Other than that, it looks great.

How do you guys work on this, and do you need help? Looks like a fun project with a reasonable scope.

One thing that slightly bothered me: the generated factory is final and you can't mock its behavior in tests. There's always the option to have a Factory interface that has the correct create method, use that everywhere and then have a provider method for it, but it kind of defeat the purpose.

E.g. some object wants a CoffeeFactory, when I test it I'd rather give it a CoffeeFactory that returns a mock Coffee. I could do that if CoffeeFactory wasn't final. Thoughts?



--
You received this message because you are subscribed to the Google Groups "Dagger Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dagger-discus...@googlegroups.com.
To post to this group, send email to dagger-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Pierre-Yves Ricau

Thomas Broyer

unread,
May 2, 2014, 5:38:40 AM5/2/14
to dagger-...@googlegroups.com


On Friday, May 2, 2014 9:14:17 AM UTC+2, Pierre-Yves Ricau wrote:
Hi,

I just tried adding AutoFactory in Square Register. We have a few places with factories that are almost 1:1 mapping of what AutoFactory generates, except we wrote them manually :) .

I had to do a few maven trickeries: exclusions (dagger and AutoFactory don't depend on the same javawriter and guava), also downgrade dagger version. Other than that, it looks great.

How do you guys work on this, and do you need help? Looks like a fun project with a reasonable scope.

One thing that slightly bothered me: the generated factory is final and you can't mock its behavior in tests. There's always the option to have a Factory interface that has the correct create method, use that everywhere and then have a provider method for it, but it kind of defeat the purpose.

It just makes it similar to, and as verbose (certainly not more at least) as Guice's AssistedInject.

AFAICT, the goal is mostly that you'll never forget to use a Provider<> as dependency in your factory.

Christian Gruber

unread,
May 2, 2014, 1:28:47 PM5/2/14
to dagger-...@googlegroups.com
Actually, we should make it non-final for mocking. There is seldom a
reason to subclass, but I think it's not unreasonable to permit it for
mocking purposes.

As to the goal, the main motivation for me was to prevent people from
creating arbitrary scopes/graphs just to wrap state of shorter-lifetime
that should just be on the call-stack, like value objects. If you have
a type that needs combination of short-lived value objects and
collaborators, auto-factory is the way to get those put together without
torturing your design with micro-scoped injectables.

I think we need to either pull dagger from auto-factory, or migrate to
Dagger 2.0 which has no runtime, so we don't pollute the dependency
graph. Likewise, we should "shade" (jar-jar, whatever) the javawriter
so we have an internal copy in the processor so we don't create
dependency conflicts with other processors that use javawriter, but
maybe have a different version.

I'll get on some of that next week.

c.

Pierre-Yves Ricau

unread,
May 2, 2014, 10:53:11 PM5/2/14
to dagger-...@googlegroups.com
2014-05-02 10:28 GMT-07:00 'Christian Gruber' via Dagger Discuss <dagger-...@googlegroups.com>:
Actually, we should make it non-final for mocking.  There is seldom a reason to subclass, but I think it's not unreasonable to permit it for mocking purposes.' 

As to the goal, the main motivation for me was to prevent people from creating arbitrary scopes/graphs just to wrap state of shorter-lifetime that should just be on the call-stack, like value objects.  If you have a type that needs combination of short-lived value objects and collaborators, auto-factory is the way to get those put together without torturing your design with micro-scoped injectables. 

I think we need to either pull dagger from auto-factory, or migrate to Dagger 2.0 which has no runtime, so we don't pollute the dependency graph.  Likewise, we should "shade" (jar-jar, whatever) the javawriter so we have an internal copy in the processor so we don't create dependency conflicts with other processors that use javawriter, but maybe have a different version.

I'm fine with whatever approach (dagger 2 / jarjar), but yeah AutoFactory should not bring any dependency into the classpath otherwise it's a mess. 
 

I'll get on some of that next week.

Awesome
 


c.


On 2 May 2014, at 5:38, Thomas Broyer wrote:

It just makes it similar to, and as verbose (certainly not more at least)
as Guice's AssistedInject.

AFAICT, the goal is mostly that you'll never forget to use a Provider<> as
dependency in your factory.

--
You received this message because you are subscribed to the Google Groups "Dagger Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dagger-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to dagger-discuss@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Kirill Rakhman

unread,
Jun 18, 2014, 11:11:50 AM6/18/14
to dagger-...@googlegroups.com
Any news here? Autofactory still doesn't work with Dagger 1.2.1.

Christian Gruber

unread,
Jun 21, 2014, 3:20:49 PM6/21/14
to dagger-...@googlegroups.com
Sorry - it's been a bit of a focus on the Truth testing library and
Dagger 2. I need to jarjar/shade/whatever the dependencies and then it
will work with dagger. I'll try to get that done next week.

c.
> --
> You received this message because you are subscribed to the Google
> Groups "Dagger Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to dagger-discus...@googlegroups.com.
> To post to this group, send email to dagger-...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Christian Gruber :: Google, Inc. :: Java Core Libraries :: Dependency
Injection
email: cgr...@google.com :::: mobile: +1 (646) 807-9839
Reply all
Reply to author
Forward
0 new messages