No dudes en compartir nuestro espacio y códigos con tus amigos, necesitamos de tu ayuda para hacer crecer esta comunidad.
Solución:
Actualizar
En el pasado, un HostedService era un transitorio de larga duración que actuaba efectivamente como un singleton. Desde .NET Core 3.1 es un Singleton real.
Utilizar AddHostedService
Un servicio alojado es más que un servicio único. El tiempo de ejecución “sabe” al respecto, puede decirle que comience llamando StartAsync
o pasa por llamar StopAsync()
cada vez que, por ejemplo, se recicla el grupo de aplicaciones. El tiempo de ejecución puede esperar a que finalice el servicio alojado antes de que finalice la propia aplicación web.
Como la documentación explica un servicio de alcance lata consumirse creando un ámbito dentro del método de trabajo del servicio alojado. Lo mismo se aplica a los servicios transitorios.
Para hacerlo, se debe inyectar un IServicesProvider o un IServiceScopeFactory en el constructor del servicio alojado y usarlo para crear el alcance.
Tomando prestado de los documentos, el constructor del servicio y el método de trabajo pueden verse así:
public IServiceProvider Services get;
public ConsumeScopedServiceHostedService(IServiceProvider services,
ILogger logger)
Services = services;
_logger = logger;
private void DoWork()
using (var scope = Services.CreateScope())
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService();
scopedProcessingService.DoWork();
Esta pregunta relacionada muestra cómo usar un DbContext transitorio en un servicio alojado:
public class MyHostedService : IHostedService
private readonly IServiceScopeFactory scopeFactory;
public MyHostedService(IServiceScopeFactory scopeFactory)
this.scopeFactory = scopeFactory;
public void DoWork()
using (var scope = scopeFactory.CreateScope())
var dbContext = scope.ServiceProvider.GetRequiredService();
…
…
Actualizar
En algún lugar entre .Net Core 2.2 y 3.1, el comportamiento ha cambiado, AddHostedService ahora está agregando un Singleton en lugar del servicio transitorio anterior. Crédito – LeonG
public static class ServiceCollectionHostedServiceExtensions
///
/// Add an registration for the given type.
///
/// An to register.
/// The to register with.
/// The original .
public static IServiceCollection AddHostedService<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] THostedService>(this IServiceCollection services)
where THostedService : class, IHostedService
services.TryAddEnumerable(ServiceDescriptor.Singleton());
return services;
///
/// Add an registration for the given type.
///
/// An to register.
/// The to register with.
/// A factory to create new instances of the service implementation.
/// The original .
public static IServiceCollection AddHostedService(this IServiceCollection services, Func implementationFactory)
where THostedService : class, IHostedService
services.TryAddEnumerable(ServiceDescriptor.Singleton(implementationFactory));
return services;
Referencia ServiceCollectionHostedServiceExtensions
Respuesta Original
Son similares pero no del todo
AddHostedService
es parte de Microsoft.Extensions.Hosting.Abstractions
.
Pertenece a Microsoft.Extensions.Hosting.Abstractions
en el ServiceCollectionHostedServiceExtensions
clase
using Microsoft.Extensions.Hosting;
namespace Microsoft.Extensions.DependencyInjection
public static class ServiceCollectionHostedServiceExtensions
///
/// Add an registration for the given type.
///
/// An to register.
/// The to register with.
/// The original .
public static IServiceCollection AddHostedService(this IServiceCollection services)
where THostedService : class, IHostedService
=> services.AddTransient();
Tenga en cuenta que está usando Transient
alcance de por vida y no Singleton
Internamente, el marco agrega todos los servicios alojados a otro servicio (HostedServiceExecutor
)
public HostedServiceExecutor(ILogger logger,
IEnumerable services) //<<-- note services collection
_logger = logger;
_services = services;
al inicio que es un singleton a través de WebHost Constructor.
_applicationServiceCollection.AddSingleton();
Si posees alguna suspicacia o capacidad de refinar nuestro crónica puedes ejecutar una reseña y con deseo lo interpretaremos.