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

Feature request: Ability to configure IBlazorDownloadFileService lifetime #20

Closed
Anil86 opened this issue Aug 26, 2020 · 9 comments
Closed
Assignees
Labels
enhancement New feature or request

Comments

@Anil86
Copy link

Anil86 commented Aug 26, 2020

I need a singleton instance of BlazorDownloadFileService (internal class).

Please allow configuring registering IBlazorDownloadFileService.

Expected api:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddBlazorDownloadFile(Microsoft.Extensions.DependencyInjection.ServiceLifetime lifetime);
    }
}


EF.Core allows configuring DbContext lifetime.

public static IServiceCollection Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.AddDbContext<TContext>(
    [NotNull] this IServiceCollection serviceCollection,
    [CanBeNull] Action<DbContextOptionsBuilder> optionsAction = null,
    ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
    ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
@arivera12 arivera12 self-assigned this Aug 26, 2020
@arivera12 arivera12 added enhancement New feature or request good first issue Good for newcomers and removed good first issue Good for newcomers labels Aug 26, 2020
@arivera12
Copy link
Owner

arivera12 commented Aug 26, 2020

I will take a look on how to implement this when I have some free time. You can fork and make pull request if you want to contribute.

@arivera12
Copy link
Owner

I took a look on the web and looks easy to implement.

@arivera12
Copy link
Owner

Install-Package BlazorDownloadFile -Version 2.1.2

@Anil86
Copy link
Author

Anil86 commented Aug 26, 2020

The new api allows specifying IBlazorDownloadFileService lifetime.
I'm getting following error:

System.InvalidOperationException: Cannot resolve scoped service 'Microsoft.JSInterop.IJSRuntime' from root provider.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
...
...

Probably Microsoft.JSInterop.IJSRuntime must be registered as singleton.

@arivera12
Copy link
Owner

arivera12 commented Aug 26, 2020

I never test changing the lifetime of the service.

Now that I remember, initially I tried setting BlazorDownloadFileService as a singleton by default and I crash into this error.

There was a explanation for this and is when you declare a Singleton service it forces to initialize at that instance, when service collection are initializing IJSRuntime is not available from the service provider.

In general explanation: if you are setting up a service than depends on another service the Singleton will trow this exception always

When you use Scoped or Transient the instance gets initialize when you use it (Inject), that's the reason why Singleton won't work on this case unless we expose the JSRuntime property and you set it after WebAssemblyHost host = builder.Build();.

But doing this I don't think it's a good idea.

It may broke the Service at any time.

I don't think there is not anything else I can do here.

Why are you needing BlazorDownloadFileService as a Singleton.

@Anil86
Copy link
Author

Anil86 commented Aug 26, 2020

I think what you are saying is that singleton services are immediately initialized while their dependencies may not have been initialized yet.


Why are you needing BlazorDownloadFileService as a Singleton?

I'm queueing jobs using Hangfire.
Method to add a job: BackgroundJob.Enqueue<Service>(Job).
Hangfire instantiates new Service for every job added.
I was trying to register Service as a Singleton so that all the jobs can share same Service property value.

@arivera12
Copy link
Owner

arivera12 commented Aug 26, 2020

I can recommend you 2 options:

  1. Make BlazorDownloadFileService a Transient service and try again.
  2. Move BlazorDownloadFileService into a global scope in your context and past it down to your function globally and try again.

Let me know if any of those options worked for you.

If not let me know so I will add the modifications to make BlazorDownloadFileService available as a Singleton.

@Anil86
Copy link
Author

Anil86 commented Aug 26, 2020

  1. Making BlazorDownloadFileService a Transient service didn't work
  2. Storing BlazorDownloadFileService as a static variable in Startup.cs worked partially.

Still got the error:

System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

I'm thinking of a simpler approach to have a single Job which will call dependent Service methods.
Thus Service doesn't need to be a Singleton.

@arivera12
Copy link
Owner

arivera12 commented Aug 26, 2020

System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

Try using OnAfterRenderAsync instead of OnInitializedAsync.

The IJSRuntime is not available OnInitializedAsync lifetime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants