0

I've got a table of products plans and subscriptions in my application, and I have created a PaypalSyncService with methods to sync these tables with tables from the Paypal API.

  public class PaypalSyncService
    {
        private readonly EzGigDbContext _context;
        private readonly PaypalService _paypalService;

        public PaypalSyncService(EzGigDbContext context, PaypalService paypalService)
        {
            _context = context;
            _paypalService = paypalService;
        }

        public async Task Sync()
        {
            await SyncProducts();
            await SyncPlans();
            await SyncSubscriptions();
        }
// other methods
    }

I then created a PaypalHostedService to run those sync operations once an hour

   public class PaypalSyncHostedService : IHostedService, IDisposable
    {
        private readonly IServiceScopeFactory _serviceScopeFactory;
        private readonly PaypalSyncService _paypalSyncService;
        private Timer _timer;
        //private readonly ILogger<PaypalSyncHostedService> _logger;

        public PaypalSyncHostedService(PaypalSyncService paypalSyncService, IServiceScopeFactory serviceScopeFactory/*, ILogger<PaypalSyncHostedService> logger*/)
        {
            _paypalSyncService = paypalSyncService;
            _serviceScopeFactory = serviceScopeFactory;
            //_logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoSync, null, TimeSpan.Zero, TimeSpan.FromHours(1));

            return Task.CompletedTask;
        }

        private void DoSync(object state)
        {
            try
            {
                using (var scope = _serviceScopeFactory.CreateScope())
                {
                    var paypalSyncService = scope.ServiceProvider.GetRequiredService<PaypalSyncService>();
                    paypalSyncService.Sync().Wait();
                }
            }
            catch (Exception ex)
            {
                //_logger.LogError(ex, "Error occurred while syncing with Paypal");
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _timer?.Change(Timeout.Infinite, 0);
            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }

But when I add the PaypalHostedService to my list of services in Startup.cs (ConfigureServices)

            services.AddScoped<EzGigDbContext>();
            services.AddScoped<ShiftService>();
            services.AddScoped<PaypalService>();
            services.AddScoped<OrganisationService>();
            services.AddScoped<LoginService>();
            services.AddScoped<PaypalSyncService>();
            services.AddScoped<IHostedService, PaypalSyncHostedService>();
            services.AddScoped<SubscriptionManagementService>();
            services.AddScoped <UserService>();

I get the following error if I have my PaypalSyncHostedService as a Scoped variable in the service

System.InvalidOperationException
  HResult=0x80131509
  Message=Cannot resolve scoped service 'System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Hosting.IHostedService]' from root provider.
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   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)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__9.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at EzGig.Program.Main(String[] args) in C:\Users\johnm\source\repos\EzGig\Program.cs:line 14

  This exception was originally thrown at this call stack:
    [External Code]
    EzGig.Program.Main(string[]) in Program.cs

and if I try to change the PaypalHostedService to a Singleton, I get the following error

System.AggregateException
  HResult=0x80131500
  Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: EzGig.Services.PaypalSyncHostedService': Cannot consume scoped service 'EzGig.Services.PaypalSyncService' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.)
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at EzGig.Program.Main(String[] args) in C:\Users\johnm\source\repos\EzGig\Program.cs:line 14

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: EzGig.Services.PaypalSyncHostedService': Cannot consume scoped service 'EzGig.Services.PaypalSyncService' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.

Inner Exception 2:
InvalidOperationException: Cannot consume scoped service 'EzGig.Services.PaypalSyncService' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.

I've tried both services as singleton, but that also threw an error. Could anyone point me in the right direction?

JohnD91
  • 523
  • 1
  • 5
  • 16

0 Answers0