Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject LocalStorage in C# file #77

Closed
rad765 opened this issue May 17, 2020 · 8 comments
Closed

Inject LocalStorage in C# file #77

rad765 opened this issue May 17, 2020 · 8 comments
Labels
Question Question about this project Resolved: Answered The question raised by the author has been answered

Comments

@rad765
Copy link

rad765 commented May 17, 2020

I'm trying to inject LocalStorage in my own Service, sa shown below.
But LocalStorage is still sett to null in the function ConsumeCollection.

The HTTP injection is OK, and injection in a razor file is OK

using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

using Blazored.LocalStorage;

using Microsoft.AspNetCore.Components;

namespace Padleloggen.Data
{
public class DataService
{
[Inject]
private HttpClient Http { get; set; }

    [Inject]
    private ILocalStorageService LocalStorage { get; set; }

    public DataService(HttpClient hc, ILocalStorageService ls)
    {
        Http = hc;
        LocalStorage = ls;
    }

    public async Task<string> ConsumeCollection<T>(string sUri) where T : IBaseElement, new()
    {
        List<T> collection = await Http.GetFromJsonAsync<List<T>>(sUri);
        string key = typeof(T).Name.ToString() + "List";
        await LocalStorage.SetItemAsync(key, collection);
        return Http == null ? "null" : key;
    }

}
}

@rad765 rad765 added Question Question about this project Triage Issue needs to be triaged labels May 17, 2020
@chrissainty
Copy link
Member

You appear to be mixing constructor injection and property injection in your code sample. If you're injecting the ILocalStorageService into a regular class, just use constructor injection, see code below.

using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

using Blazored.LocalStorage;

using Microsoft.AspNetCore.Components;

namespace Padleloggen.Data
{
    public class DataService
    {
        private HttpClient Http;
        private ILocalStorageService LocalStorage

        public DataService(HttpClient hc, ILocalStorageService ls)
        {
            Http = hc;
            LocalStorage = ls;
        }

        public async Task<string> ConsumeCollection<T>(string sUri) where T : IBaseElement, new()
        {
            List<T> collection = await Http.GetFromJsonAsync<List<T>>(sUri);
            string key = typeof(T).Name.ToString() + "List";
            await LocalStorage.SetItemAsync(key, collection);
            return Http == null ? "null" : key;
        }
    }
}

@chrissainty chrissainty added Resolved: Answered The question raised by the author has been answered and removed Triage Issue needs to be triaged labels May 18, 2020
@rad765
Copy link
Author

rad765 commented May 18, 2020

You are right with respect to the mixing of dependency modells, but still I have a problem with LoacalStorageService, It does not inject properly .

The code below is OK, but uncommenting the ILocatStorageService vil give me the following messeage in Blazor: "An unhandled error has occured. Reload;

public class DataService
{
private HttpClient Http { get; set; }

    private ILocalStorageService LocalStorage { get; set; }

    public DataService(HttpClient hc)//, ILocalStorageService ls)
    {
        Http = hc;
  //      LocalStorage = ls;

}

     public async Task<string> ConsumeCollection<T>(string sUri) where T : IBaseElement, new()
     {
         List<T> collection = await Http.GetFromJsonAsync<List<T>>(sUri);
         string key = typeof(T).Name.ToString() + "List";
   //      await LocalStorage.SetItemAsync(key, collection);
         return Http == null ? "null" : key;
     } 

@intech-paul
Copy link

intech-paul commented May 18, 2020

You could put a try/catch block around the code causing the error to get more info that what you are getting, also you can look the the browser console as well.

try {
Do This();
}
catch (Exception ex)
{
Console.WriteLine(ex.message)
}

The blazor unhandled error is not very helpful.

@chrissainty
Copy link
Member

@rad765 As this code is in a service, when is it being executed? And are you running this from Blazor Server or Blazor Wasm?

@rad765
Copy link
Author

rad765 commented May 19, 2020

I guess, I have learned a lesson about lifetime and scope of services. I was registering my Service as a singleton which probably is OK in Blazor Server. In Blazor Wasm this probably does not make sense. Registering my service as Scoped solved the problem.
Thought your answers/questions did not directly solve my problem, they guided me in the right direction, so thank you very much for the help.

@chrissainty
Copy link
Member

Glad you got it sorted but I'm a bit concerned about something you said. Singletons in Blazor Server will deliver the same instance to all users of your application, which is usually not the intended behaviour. Singleton and scoped services in Blazor Wasm act exactly the same so it doesn't matter which you choose.

@rad765
Copy link
Author

rad765 commented May 20, 2020

And here I thought that I have learned something...
The behaviour is reproduceable. Create at new Blazor wasm project.
Ad this simple service:

        using Blazored.LocalStorage;

        namespace SingletonTest.Data
       {
           public class DataService
          {
                private ILocalStorageService LocalStorage { get; set; }
                public DataService(ILocalStorageService ls)
               {
                    LocalStorage = ls;
               }
         }
     }

In Index.razor add:

        @inject DataService DS

Add this to your Program.cs

       builder.Services
            .AddBlazoredLocalStorage()
            .AddScoped<DataService>();  // This is OK
            //.AddSingleton<DataService>();  // This is not OK

@chrissainty
Copy link
Member

chrissainty commented May 20, 2020

Ahh yes, it's because the Blazored services are injected as scoped, you can't inject scoped services into singletons as the lifetime of the singleton is longer than the lifetime of the injected service.

This is the standard behaviour of the .NET DI container.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question Question about this project Resolved: Answered The question raised by the author has been answered
Projects
None yet
Development

No branches or pull requests

3 participants