I have a service that uses Flurl
; the service always sets BasicAuth
credentials based on a configuration flag. This is no longer the case, and I need to change the credentials based on data that isn't available when the dependency is provided.
Is there a way to modify how Flurl authenticates after creating a new client?
The setup (greatly simplified but sufficient) is as follows:
public class MyClient : IMyClient, IDisposable
{
private readonly IFlurlClient _client;
public MyClient(IFlurlClientFactory flurlClientFactory)
{
var baseUrl = config.BaseUrl;
_client = flurlClientFactory
.Get(new Url(baseUrl))
.WithBasicAuth("my", "credentials");
}
public async Task<MyProcessResponse> MyProcess(MyProcessRequest processRequestData)
{
var resource = GetProcessResource();
// I need to change credentials here, based on data within resouce.
var response = await _client.Request(resource)
.PostJsonAsync(processRequestData)
.ReceiveJson<MyProcessResponse>();
return response;
}
}
The service is used as such:
public class Process : IProcess
{
private readonly IMyClient _myClient
public Process(IMyClient myClient)
{
_myClient = myclient;
}
private async Task<bool> RunProcess()
{
var processRequestData = GetProcessRequestData()
await _myClient.MyProcess(processRequestData);
// do stuff
}
}
As the environment is no longer the only factor, I need to change/set the credentials based on data defined within processRequestData
.
It is my understanding I shouldn't be creating multiple clients, hence creating the one which has (so far) served its purpose.
What's the sanest way of achieving this?
Using the dated .NET 4.8 with MVC with AutoFac handling the DI.
You can call WithBasicAuth
at any point, so this is a case of moving WithBasicAuth
outside of the constructor, into MyProcess
and then providing the relevant parameters.
public class MyClient : IMyClient, IDisposable
{
private readonly IFlurlClient _client;
public MyClient(IFlurlClientFactory flurlClientFactory)
{
var baseUrl = config.BaseUrl;
_client = flurlClientFactory
.Get(new Url(baseUrl));
}
public async Task<MyProcessResponse> MyProcess(MyProcessRequest processRequestData)
{
var resource = GetProcessResource();
var credentials = BuildCredentials(resource);
_client.WithBasicAuth(credentials.Username, credentials.Password);
var response = await _client.Request(resource)
.PostJsonAsync(processRequestData)
.ReceiveJson<MyProcessResponse>();
return response;
}
}
I didn't realise this and obviously wasn't paying enough attention to IntelliSense and/or documentation.