I'm trying to inject and use a service directly in Startup.cs in my Blazor application (MVVM). When I try to call a method from that service, I receive the same error message as when you failed to register the service properly:
I am doing this to read a value from the localstorage to set the language in startup.cs. for further information, see:
https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-6.0&pivots=server#dynamically-set-the-culture-by-user-preference-1
This is how I added the service in Startup.cs:
Injecting:
public class Startup
{
private IStorageService storageService;
public Startup(IConfiguration configuration, IStorageService storageService)
{
this.storageService = storageService;
Configuration = configuration;
}
public IConfiguration Configuration { get; }
RegisterLocation:
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IStorageService, StorageService>();
var circuitRetentionPeriod = Configuration.GetValue("DisconnectedCircuitRetentionPeriodInMinutes", 3);
services.AddRazorPages();
services.AddServerSideBlazor()
.AddCircuitOptions(a => a.DisconnectedCircuitRetentionPeriod = System.TimeSpan.FromMinutes(circuitRetentionPeriod))
.AddHubOptions(hub => hub.MaximumReceiveMessageSize = 100 * 128 * 128); // 100 MB
// Add basic logging functionality
services.AddLogging(loggingBuilder =>
{
// Clear all potential logging providers
loggingBuilder.ClearProviders();
// Add NLog which will output the log to a log file
loggingBuilder.AddNLog();
// Log output to the Visual Studio Debug output
loggingBuilder.AddDebug();
});
services.AddScoped<CircuitHandler>((sp) => new CircuitHandlerService(sp.GetRequiredService<ILogger<CircuitHandlerService>>(), sp.GetRequiredService<CircuitsCounterService>()));
services.AddSingleton<CircuitsCounterService>();
services.AddScoped<CorrelationProvider>();
services.AddAppBaseBlazorServices();
services.AddAppBaseApplicationServices();
services.AddApplicationServices();
services.AddBlazorServices();
services.AddForeignServices();
}
UseService:
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var language = storageService.Load<LanguageDTO>(StorageKeys.Language);
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
Implementation of StorageService.Load()
public StorageService(ILocalStorageService storage, ILogger<StorageService> logger)
{
this.logger = logger is null ? new NullLogger<StorageService>() : logger;
this.storage = storage;
}
public async Task<T> Load<T>(string key)
where T : class, new()
{
try
{
var jsonString = await storage.GetItemAsStringAsync(key);
if (string.IsNullOrEmpty(jsonString))
{
logger.LogTrace("Local storage item with key '{}' not found. Return new object.", key);
return new T();
}
if (!jsonString.StartsWith("{"))
{
// No matter if the data is encrypted try to decrypt the value and swallow if the data was not encrypted
try { jsonString = StringCipher.Decrypt(jsonString, PASSPHRASE); }
catch (FormatException) { }
}
if (logger.IsEnabled(LogLevel.Trace))
{
var jDoc = JsonDocument.Parse(jsonString, new JsonDocumentOptions { AllowTrailingCommas = true });
jsonString = System.Text.Json.JsonSerializer.Serialize(jDoc, new JsonSerializerOptions { WriteIndented = true });
logger.LogTrace("Load value from local storage with key '{key}': {jsonString}", key, jsonString);
}
// Deserialize the object
var result = JsonConvert.DeserializeObject<T>(jsonString);
if (result is null)
return new T();
else
return result;
}
catch (JSDisconnectedException)
{
// This exception es expected when the application try to load something but the Blazor circuit is closed i.e. when the page is refreshed with f5
return new T();
}
I also tried to register the service at the top of ConfigureServices, in case the previous location is too late.
Furthermore, I already found out on the internet and ChatGPT, that this should be totally possible. But can't find out what I am doing wrong.