Reputation: 82341
I have a method in my NuGet package library that looks like this:
public async Task<string> GetLogoutUrl(HttpContext httpContext, string encodedUserJwt, string relativeRedirectUrl)
{
var redirectUrl = $"{httpContext.Request.Scheme}://{httpContext.Request.Host}/{relativeRedirectUrl}";
var logoutUrlParameters = $"id_token_hint={encodedUserJwt}&post_logout_redirect_uri={redirectUrl}";
var logoutUrl = $"{await DiscoveryDocument.GetLogoutEndpoint()}?{logoutUrlParameters}";
return logoutUrl;
}
I would really like to make it an extension method of HttpContext
so the users of my NuGet can call it like this: HttpContext.GetLogoutUrl(encodedUserJwt, "Home");
But the problem with that is that this method uses DiscoveryDocument
that is injected into the class where this method currently resides. I have been trying to think of a way I could get the nice syntax of an extension method, but still be able to get the DiscoveryDocument
from dependency injection while not breaking so many best practices that I can't sleep at night.
Is there a way in C# to have an extension method and still connect to a dependency injected object?
NOTE: I don't want to make the developers that use my NuGet to have to pass in an instance of DiscoveryDocument
. For the architecture of my NuGet that would be worse than just having GetLogoutUrl
not be an extension method.
Upvotes: 3
Views: 1372
Reputation: 247098
Service locator via
IServiceProvider HttpContext.RequestServices { get }
will have to be used since this is a static call , which does not usually play well with DI since it is usually centered around instances.
The potential extension method would end up looking something like this
public static async Task<string> GetLogoutUrl(this HttpContext httpContext,
string encodedUserJwt, string relativeRedirectUrl) {
var redirectUrl = $"{httpContext.Request.Scheme}://{httpContext.Request.Host}/{relativeRedirectUrl}";
var logoutUrlParameters = $"id_token_hint={encodedUserJwt}&post_logout_redirect_uri={redirectUrl}";
var DiscoveryDocument = httpContext.RequestServices
.GetRequiredService<DiscoveryDocumentTypeHere>();
var logoutUrl = $"{await DiscoveryDocument.GetLogoutEndpoint()}?{logoutUrlParameters}";
return logoutUrl;
}
Upvotes: 3