2011-02-11 9 views
32

Estoy creando un servicio de grises que interactuará con una API REST de un tercero a través de una biblioteca Java. La biblioteca Java requiere credenciales para la API REST por medio de una url, nombre de usuario y contraseña.Inyectar la aplicación de aplicación de grises en el servicio

Me gustaría almacenar estas credenciales en configuration/Config.groovy, ponerlas a disposición de un servicio y garantizar que las credenciales estén disponibles para el servicio antes de que las requiera.

I apreciarán que grailsApplication.config está disponible para los controladores y que a través de un método de un servicio de los valores de configuración relevantes se pueden proporcionar para el servicio, como este:

package example 

class ExampleController { 

    def exampleService 

    def index = { } 

    def process = { 
     exampleService.setCredentials(grailsApplication.config.apiCredentials) 
     exampleService.relevantMethod() 
    } 
} 


package example 

import com.example.ExampleApiClient; 

class ExampleService { 

    def credentials 

    def setCredentials(credentials) { 
     this.credentials = credentials 
    } 

    def relevantMethod() { 

     def client = new ExampleApiClient(
      credentials.baseUrl, 
      credentials.username, 
      credentials.password 
     ) 

     return client.action(); 
    } 
} 

Siento que este enfoque es un poco defectuoso ya que depende de un controlador que llame al setCredentials(). Tener las credenciales disponibles para el servicio automágicamente sería más sólido.

(no me la actualidad lo suficientemente familiarizado con griales) ¿Es alguna de estas dos opciones viables:

  1. Inyectar grailsApplication.config.apiCredentials en el servicio en el controlador cuando se crea el servicio?

  2. Proporcione algún tipo de contructor en el servicio que permita pasar las credenciales al servicio en el momento de creación de instancias?

Tener las credenciales inyectadas en el servicio es ideal. ¿Como se puede hacer esto?

+1

seguiría siendo bueno si hubiera alguna manera de inyectar las propiedades de configuración reales en lugar de todo el objeto grailsApplication. –

Respuesta

73

El objeto grailsApplication está disponible dentro de los servicios, permitiendo esto:

package example 

import com.example.ExampleApiClient; 

class ExampleService { 

    def grailsApplication 

    def relevantMethod() { 

     def client = new ExampleApiClient(
      grailsApplication.config.apiCredentials.baseUrl 
      grailsApplication.config.apiCredentials.username, 
      grailsApplication.config.apiCredentials.password 
     ) 

     return client.action(); 
    } 
} 
+10

Tenga en cuenta que he encontrado que necesita usar grailsApplication.config [...] dentro de un método. De lo contrario, verá un puntero nulo si intenta extraer los datos del archivo de configuración fuera de un método. – arcdegree

+0

Gracias @arcdegree. Tu comentario me ahorró mucha frustración. – aa8y

3

Para contextos donde no se puede inyectar el grano grailsApplication (servicio no es uno de aquellos, como se describe por Jon Cram), por ejemplo una clase de ayuda situado en src/maravilloso, se puede acceder a él mediante los titulares clase:

def MyController { 
    def myAction() { 
     render grailsApplication == grails.util.Holders.grailsApplication 
    } 
} 
10

aunque grailsApplication se puede inyectar en los servicios, creo que los servicios Shou No tiene que lidiar con la configuración porque es más difícil de probar y rompe el Single Responsibility principle. Spring, en el otro lado, puede manejar la configuración e instanciación de una manera más robusta. Grails tiene a dedicated section en sus documentos.

Para hacer su trabajo ejemplo utilizando Spring, debe registrar su servicio como un grano en resources.groovy

// Resources.groovy 
import com.example.ExampleApiClient 

beans { 
    // Defines your bean, with constructor params 
    exampleApiClient ExampleApiClient, 'baseUrl', 'username', 'password' 
} 

Entonces usted será capaz de inyectar la dependencia en su servicio

class ExampleService { 
    def exampleApiClient 

    def relevantMethod(){ 
     exampleApiClient.action() 
    } 
} 

Además , en su archivo Config.groovy, puede anular cualquier propiedad de bean utilizando la convención de Grails sobre la sintaxis de configuración: beans.<beanName>.<property>:

// Config.groovy 
... 
beans.exampleApiClient.baseUrl = 'http://example.org' 

Ambos Config.groovy y resources.groovy admiten una configuración de entorno diferente.

Cuestiones relacionadas