////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////


==== Dependency Injection Basics

A key aspect of Grails services is the ability to use https://www.springframework.org/[Spring Framework]'s dependency injection features. Grails supports "dependency injection by convention". In other words, you can use the property name representation of the class name of a service to automatically inject them into controllers, tag libraries, and so on.

As an example, given a service called `BookService`, you can define a property called `bookService` in a controller as follows:

[source,groovy]
----
class BookController {
    BookService bookService
    ...
}
----

In this case, the Spring container will automatically inject an instance of that service based on its configured scope. Since all dependency injection is done by name you can also specify the type as follows:

[source,groovy]
----
class AuthorService {
    BookService bookService
}
----

NOTE: NOTE: Normally the property name is generated by lower casing the first letter of the type.  For example, an instance of the `BookService` class would map to a property named `bookService`.

To be consistent with standard JavaBean conventions, if the first 2 letters of the class name are upper case, the property name is the same as the class name.  For example, the property name of the `JDBCHelperService` class would be `JDBCHelperService`, not `jDBCHelperService` or `jdbcHelperService`.

See section 8.8 of the JavaBean specification for more information on de-capitalization rules.

NOTE: Only the top level object is subjected to injection as traversing all nested objects to perform injection would be a performance issue.

Be careful when injecting the non-default datasources. For example, using this config:

[source,yaml]
----
dataSources:
    dataSource:
        pooled: true
        jmxExport: true
	...
    secondary:
        pooled: true
        jmxExport: true
	...
----

You can inject the primary `dataSource` like you would expect:

[source,groovy]
----
class BookSqlService {
      DataSource dataSource
}
----

But to inject the `secondary` datasource, you have to use Spring's `Autowired` injection or `resources.groovy`.

[source,groovy]
----
class BookSqlSecondaryService {

  @Autowired
  @Qualifier('dataSource_secondary')
  DataSource dataSource2
}
----

==== Dependency Injection and Services

You can inject services in other services with the same technique. If you had an `AuthorService` that needed to use the `BookService`, declaring the `AuthorService` as follows would allow that:

[source,groovy]
----
class AuthorService {
    BookService bookService
}
----

==== Dependency Injection and Domain Classes / Tag Libraries

You can even inject services into domain classes and tag libraries, which can aid in the development of rich domain models and views:

[source,groovy]
----
class Book {
    ...
    BookService bookService

    def buyBook() {
        bookService.buyBook(this)
    }
}
----

WARNING: Since Grails 3.2.8 this is not enabled by default. If you want to enable it again, take a look at https://grails.apache.org/docs/latest/ref/Domain%20Classes/Usage.html#_spring_autowiring_of_domain_instances[Spring Autowiring of Domain Instance]

==== Service Bean Names

The default bean name which is associated with a service can be problematic if there are multiple services with the same name defined in different packages.  For example consider the situation where an application defines a service class named `com.demo.ReportingService` and the application uses a plugin named `ReportingUtilities` and that plugin provides a service class named `com.reporting.util.ReportingService`.

The default bean name for each of those would be `reportingService` so they would conflict with each other.  Grails manages this by changing the default bean name for services provided by plugins by prefixing the bean name with the plugin name.

In the scenario described above the `reportingService` bean would be an instance of the `com.demo.ReportingService` class defined in the application and the `reportingUtilitiesReportingService` bean would be an instance of the `com.reporting.util.ReportingService` class provided by the `ReportingUtilities` plugin.

For all service beans provided by plugins, if there are no other services with the same name within the application or other plugins in the application then a bean alias will be created which does not include the plugin name and that alias points to the bean referred to by the name that does include the plugin name prefix.

For example, if the `ReportingUtilities` plugin provides a service named `com.reporting.util.AuthorService` and there is no other `AuthorService` in the application or in any of the plugins that the application is using then there will be a bean named `reportingUtilitiesAuthorService` which is an instance of this `com.reporting.util.AuthorService` class and there will be a bean alias defined in the context named `authorService` which points to that same bean.
