Injecting context into a "service"

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Injecting context into a "service"

Bertrand Quenin
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Marcin Erdmann
Yes, it is possible to inject Context into a Guice managed instance (if that's what you mean by service, basically what you would call a bean in Spring). I would advise against doing so in general and thus would like to ask why do you want to do so.

To inject a context you'll first need to expose it in execution scope (a custom Guice scope that Ratpack provides) by writing a provider for it in a module:

@Provides
@ExecutionScoped
public Context provideContext(Execution execution) {
  return execution.get(Context);
}

and then inject a provider (javax.inject.Provider or com.google.inject.Provider) for it into your service  - assuming that your service is in Singleton scope or in "no scope" (the one that Guice uses when you don't declare one) because they are broader scopes than the execution scope:

@Inject
public MyService(Provider<Context> contextProvider) {
  ...
}

Finally you need to obtain the context each time you want to use it inside of the service by calling contextProvider.get().
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Bertrand Quenin
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Bertrand Quenin
In reply to this post by Marcin Erdmann
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Injecting context into a "service"

Marcin Erdmann
Yeah, exactly. You usually don't need to inject context because you don't need that much - context is-a registry so injecting context is almost like injecting application context in Spring terms. It's very rarely that your service would need to know about the context unless it deals with Ratpack infrastructure. Taking good design principles into consideration you should never tell a service more than it really needs to know.

Injecting Request still wouldn't be my first choice but you have a very good reason to do so - a constraining interface you need to implement to integrate with katharsis.

One improvement would probably be exposing a service that pulls out the authenticated user from the Request and inject that service into your integration service. Feels like obtaining the user from request in your service is a bit too low level and the fact that authenticated user is obtained from the request might be considered an implementation detail (you could for example make a change to store it on the session in the future).

On Sunday, 4 October 2015, Bertrand Quenin [via Ratpack Forum] <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;ml-node%[email protected]&#39;);" target="_blank">[email protected]> wrote:
Hi, I tried your solution, but since I only needed the request, I adapted it like this:

@Provides
@RequestScoped
def protected Request provideRequest(Execution execution) {
  execution.get(Request)
}

And then injected the provider into my service:

@Singleton
class OwnerRepository extends BaseRepository<Owner> {
  @Inject
  new(Database database, Provider<Request> requestProvider) {
    super(database, requestProvider)
  }

It works using this, however, I'm still curious why is it discouraged :)



If you reply to this email, your message will be added to the discussion below:
http://forum.ratpack.io/Injecting-context-into-a-service-tp1300p1303.html
To start a new topic under Ratpack Forum, email [hidden email]
To unsubscribe from Ratpack Forum, click here.
NAML
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Marcin Erdmann
In reply to this post by Bertrand Quenin
Btw, kudos for finding out that there is request scope as well.

On Sunday, 4 October 2015, Bertrand Quenin [via Ratpack Forum] <[hidden email]> wrote:
Hi, I tried your solution, but since I only needed the request, I adapted it like this:

@Provides
@RequestScoped
def protected Request provideRequest(Execution execution) {
  execution.get(Request)
}

And then injected the provider into my service:

@Singleton
class OwnerRepository extends BaseRepository<Owner> {
  @Inject
  new(Database database, Provider<Request> requestProvider) {
    super(database, requestProvider)
  }

It works using this, however, I'm still curious why is it discouraged :)



If you reply to this email, your message will be added to the discussion below:
http://forum.ratpack.io/Injecting-context-into-a-service-tp1300p1303.html
To start a new topic under Ratpack Forum, email <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;ml-node%[email protected]&#39;);" target="_blank">[email protected]
To unsubscribe from Ratpack Forum, click here.
NAML
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Bertrand Quenin
In reply to this post by Marcin Erdmann
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Marcin Erdmann
This post was updated on .
You can inject the Request directly as it's already exposed in request scope. Using java it would be something like:

@Provides
@RequestScoped
public User provideAuthenticatedUser(Request request) {
  User user = /* extract user from request */;
  return user;
}


Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Bertrand Quenin
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: Injecting context into a "service"

Marcin Erdmann
You're welcome!