Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseClient's HttpClientInitializer property is private set, making it impossible to change cred after client is initialized, forcing unneeded recreations. Any workaround? #2064

Closed
mikequ-taggysoft opened this issue Mar 2, 2022 · 2 comments
Assignees
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.

Comments

@mikequ-taggysoft
Copy link

mikequ-taggysoft commented Mar 2, 2022

We have stored users tokens (both access and refresh) in our database and handle our own refresh logic. So we use GoogleCredential.FromAccessToken to authenticate the clients.

I'm trying to implement DI pattern for various clients (CalendarService, GmailService etc) as they're used a lot within the same class across many methods. DI would make them reusable and easy to manage.

However, the HttpClientInitializer can only be set at construction time. The problem is that our service layer codes all use DI. It is not possible for us to set user at DI constructor injection time, so we need to rely on user IDs etc passed to our service methods to retrieve the correct users' tokens and set the credentials on these clients.

Because HttpClientInitializer cannot be set after client creation, it forces us to recreate clients repeatedly.

I suspect this design may have something to do with thread safety, but since Google has batch support, I don't think running multiple clients in parallel is a good pattern, especially considering the fact that Google has various limits on per user/api/project calls.

Is there a way to make DI work in my scenario?

Would you consider making the HttpClientInitializer property public settable?

It's a bit of a pain as we're trying to build a service that works with both MS Graph and Google, and MS's GraphServiceClient doesn't have such a restriction, so we have to treat the Google side differently. 😄

@mikequ-taggysoft mikequ-taggysoft added priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue. labels Mar 2, 2022
@amanda-tarafa
Copy link
Contributor

You can use per-request credentials as follows without the need to change the credential on the service client (pardon possible typos). I believe this should cover your use case.

// From DI, no credential set. Or also a default credential set if you need to.
CalendarService client;
GoogleCredential credential = GoogleCredential.FromAccessToken(GetAccessToken(userId)); 
// Create a request with a per-call credential.
var request = client.Events.List(....).AddCredential(credential);
// If a request has a credential set, then the client service credential is ignored.
var events = request.Execute();

@mikequ-taggysoft
Copy link
Author

@amanda-tarafa Ahhh I kept looking for a method like this on the client level, somehow never thought of looking at the ClientServiceRequest level. All makes sense now. Thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

2 participants