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

Reply via email to