How would one inject doubles of the services when testing?
On Tue, May 6, 2014 at 9:59 AM, Adam Murdoch <[email protected]>wrote: > Hi, > > I recently made a change to add a new mechanism for injecting dependencies > into tasks. Previously, to inject services into a task instance we were > using either: > > 1. getServices().get(Type) or > 2. constructor injection. > > One downside with #1 is that the approach not declarative, so we can’t > figure out statically which services a task is going to use, or when. This > is important in order for us to determine things like the possible inputs > and outputs of the task, or to do any early validation, or deal with > services that require some work to make usable, and so on. > > Approach #2 addresses this issue (mostly), but has a couple of downsides > of its own. Firstly, for good or bad, we currently make the task types > public and allow them to be subclassed. This means that the implementation > services are exposed to subtypes and we can’t change the set of services > without changing the constructor - thereby breaking backwards compatibility. > > Secondly, approach #2 requires that all the services be created when the > task is created, regardless of whether the task or service is ever > required. The services are also retained for the entire life of the task > object. This has a noticeable impact on performance and heap usage in > particular. This was the main motivation for the change. > > The ‘proper’ solution here is to separate out the configuration and the > implementation pieces of a task, and defer creation of the implementation > stuff, and the services it needs, until execution time. This will be part > of the solution to allow tasks from a given project to execute in parallel. > > In the meantime, and for legacy tasks, there is a new mechanism to inject > services that addresses the downsides of #1 and #2 above. To use this, > define a getter annotated with @Inject: > > @Inject > protected MyService getMyService() { … doesn’t matter what goes in here > ... } > > When decorated, this method is replaced with a service lookup. The lookup > is lazy, so that the service is not created until the getter is called. > > This mechanism is considered incubating at this stage. It only works for > tasks for now, but would probably be useful for all decorated types (and > plugins, which aren’t decorated yet). > > > -- > Adam Murdoch > Gradle Co-founder > http://www.gradle.org > VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting > http://www.gradleware.com > > Join us for Gradle Summit 2014, June 12th and 13th in Santa Clara, CA: > http://www.gradlesummit.com > >
