One would fix TestUtil to take care of this.

On 8 May 2014, at 10:00 am, Perryn Fowler <[email protected]> wrote:

> 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
> 
> 


--
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

Reply via email to