In order to store an Oauth token in MemoryCache (.net core 3.1 API) - I found the below example (some parts left out) but I can't find a way call the constructor of the HTTPservice so it uses the memorycache.
First there's an interface definition:
public interface ITokenService
{
string FetchToken();
}
Then the interface implementation
public class TokenService : ITokenService
{
private readonly IMemoryCache cache;
public TokenService(IMemoryCache cache)
{
this.cache = cache;
}
public string FetchToken()
{
string token = string.Empty;
if (!cache.TryGetValue("TOKEN", out token))
{
var tokenValue = this.GetTokenFromApi();
var options = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(
TimeSpan.FromSeconds(3600));
cache.Set("TOKEN", tokenValue, options);
token = tokenValue;
}
return token;
}
private string GetTokenFromApi()
{
return "Test";
}
}
Then the memorycache and TokenService is added in startup.cs
services.AddMemoryCache();
services.AddSingleton<ITokenService, TokenService>();
Lastly a HTTPservice that will use the token from cache is implemented like this:
public class HttpService
{
private ITokenService token;
public HttpService(ITokenService token)
{
this.token = token;
}
public string GetReadersFromExternalApi(string requestUrl)
{
return token.FetchToken();
}
}
problem described here
To use the HTTPService
the constructor has to be called - but the constructor expects a TokenService as parameter, and the TokenService
expects IMemoryCache
in the constructor.
So i tried this line of code to make a new HTTPservice
object, but cache is empty on consecutive calls - so what parameters should be passed to the constructor in order to reference the tokenservice/memorycache?
var httpService
= new HttpService(new TokenService(new MemoryCache(new MemoryCacheOptions())));
CodePudding user response:
I think you have 2 ways to solve this:
Solution A
Inject your HttpService as scoped (instance per request) which will have the single TokenService instance and should work fine.
services.AddScoped<HttpService>();
Solution B
You may could create an instance of the HttpService by constructor but in that case you should inject the ITokenService in the same service where HttpService is being created, and pass it as parameter.
public class SomeClass
{
private readonly ITokenService _tokenService;
public SomeClass(ITokenService tokenService)
{
_tokenService = tokenService;
}
public HttpService CreateHttpService()
{
return new HttpService(_tokenService);
}
}
I would go with the first solution, but I include the second one because may be useful for you to understand the issue
CodePudding user response:
Your code here creates a new MemoryCache
every time the code is called, that means that a new cache is being created so when this code runs a second time it will use a different empty cahce than the first execution. Which is why the cache is empty.
HttpService httpService = new HttpService(new TokenService(new MemoryCache(new MemoryCacheOptions())));
Where you configure your dependency injection, you should add the following line to register your HttpService as a new dependency
services.AddSingleton<IHttpService, HttpService>();
*Note that this line will require you adding in a new IHttpService
which HttpService
implements.
Then wherever you need to access the HttpService
, you should inject the new IHttpService
and let the dependency injection contain handle everything else.
For example:
public class MyService
{
private readonly IHttpService _httpService { get; set; }
public MyService(IHttpService httpService)
{
_httpService = httpService;
}
public void MyMethod()
{
var readers = _httpService.GetReadersFromExternalApi("Example Request");
}
}