Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject DbContext in a custom localization provider in ASP.NET Core?

As explained in the asp.net core docs you can configure a custom provider for request localization. As stated in the docs:

Suppose you want to let your customers store their language and culture in your databases. You could write a provider to look up these values for the user.

For that the following code snippet is provided in the docs and also in the github sample Localization.StarterWeb:

services.Configure<RequestLocalizationOptions>(options => {
var supportedCultures = new[]
{
    new CultureInfo("en-US"),
    new CultureInfo("fr")
};

options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;

options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
{
   // My custom request culture logic
   // DbContext needed here <--
  return new ProviderCultureResult("en");
}));});

Can anybody explain me how to inject a DbContext to load the user specific language from DB in the above function?

like image 508
MDummy Avatar asked Jul 25 '16 16:07

MDummy


1 Answers

Well, you can't inject it via constructor because you need to instantiate it during ConfigureServices method and the container isn't available at this point.

Instead you can resolve via HttpContext.

public class CustomRequestCultureProvider : RequestCultureProvider
{
    // Note we don't inject any dependencies into it, so we can safely 
    // instantiate in ConfigureServices method
    public CustomRequestCultureProvider() { } 

    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        var dbContext = httpContext.RequestServices
            .GetService<AppDbContext>();
    }
}

Be aware though that this may be less than optimal, as you'll have calls to database on every request, so maybe it's worth to abstract this further and use an caching strategy depending on what exactly you want to do with the DbContext.

Usually one should avoid database calls in culture providers, filters etc. for performance reasons

Update:

There is a generic version of GetService<T>, but you need to import the namespace via using Microsoft.Extensions.DependencyInjection;.

like image 166
Tseng Avatar answered Oct 08 '22 05:10

Tseng