.NET Core 2.0 IServiceCollection отсутствует AddHostedService? - PullRequest
0 голосов
/ 07 сентября 2018

Пытается использовать:

Startup.cs

public void ConfigureServices(IServiceCollection services) {
  services.AddHostedService<LifetimeEvents>();
    .
    .
    .
}

где класс LifeTimeEvents наследуется от IHostedService. Я получаю эту ошибку:

'IServiceCollection' does not contain a definition for 'AddHostedService' and no extension method 'AddHostedService' accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?)

Кажется, я не могу найти подходящее пространство имен для использования или пакет nuget, чтобы это работало, но это работает из коробки в .NET Core 2.1, это просто не доступно в .NET Core 2.0? Есть ли способ заставить его работать?

UPDATE:

В качестве обходного пути я изменил свой код для использования:

Startup.cs

public void ConfigureServices(IServiceCollection services) {
  services.AddSingleton<LifetimeEvents>();
    .
    .
    .
}

public void Configure(IApplicationBuilder appBuilder, IHostingEnvironment envHost, LifetimeEvents appEvents)  {
  appEvents.StartAsync(new CancellationToken(false));
    .
    .
    .
}

и это похоже на работу. Не отвечает на мой первоначальный вопрос, и я не уверен, насколько это «лучшие практики», но это заставило меня перейти к рефакторингу этого приложения .NET Core 2.0.

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Я считаю, что это дублирующий вопрос к тому, на что я отвечал раньше.

Где я должен запускать постоянные фоновые задачи в ASP.NET Core?

Ниже приведен ответ, скопируйте + вставьте.

Я полагаю, вы ищете это

https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/

И я провел 2 часа самопровозглашенного хакатона, удостоенного наград, чтобы узнать, как это происходит.

https://github.com/nixxholas/nautilus

Вы можете сослаться на инъекции здесь и реализовать тезисы оттуда тоже.

Многие проекты MVC на самом деле не требуются для выполнения постоянных фоновых задач. Вот почему вы не видите их в новом проекте через шаблон. Лучше предоставить разработчикам интерфейс для подключения и продолжить его.

Кроме того, что касается открытия этого сокетного соединения для таких фоновых задач, мне еще предстоит найти решение для этого. Насколько я знаю / знаю, я мог транслировать полезную нагрузку только тем клиентам, которые подключены к моему собственному сокет-менеджеру, поэтому вам придется искать это в других местах. Я обязательно подам звуковой сигнал, если в IHostedService есть что-то, касающееся веб-сокетов.

Хорошо, в любом случае вот что происходит.

Поместите это куда-нибудь в свой проект, это скорее интерфейс для перегрузки, чтобы вы могли создать свою собственную задачу

/// Copyright(c) .NET Foundation.Licensed under the Apache License, Version 2.0.
    /// <summary>
    /// Base class for implementing a long running <see cref="IHostedService"/>.
    /// </summary>
    public abstract class BackgroundService : IHostedService, IDisposable
    {
        protected readonly IServiceScopeFactory _scopeFactory;
        private Task _executingTask;
        private readonly CancellationTokenSource _stoppingCts =
                                                       new CancellationTokenSource();

        public BackgroundService(IServiceScopeFactory scopeFactory) {
            _scopeFactory = scopeFactory;
        }

        protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

        public virtual Task StartAsync(CancellationToken cancellationToken)
        {
            // Store the task we're executing
            _executingTask = ExecuteAsync(_stoppingCts.Token);

            // If the task is completed then return it,
            // this will bubble cancellation and failure to the caller
            if (_executingTask.IsCompleted)
            {
                return _executingTask;
            }

            // Otherwise it's running
            return Task.CompletedTask;
        }

        public virtual async Task StopAsync(CancellationToken cancellationToken)
        {
            // Stop called without start
            if (_executingTask == null)
            {
                return;
            }

            try
            {
                // Signal cancellation to the executing method
                _stoppingCts.Cancel();
            }
            finally
            {
                // Wait until the task completes or the stop token triggers
                await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite,
                                                              cancellationToken));
            }
        }

        public virtual void Dispose()
        {
            _stoppingCts.Cancel();
        }
    }

Вот как вы можете его использовать

public class IncomingEthTxService : BackgroundService
    {
        public IncomingEthTxService(IServiceScopeFactory scopeFactory) : base(scopeFactory)
        {
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {

            while (!stoppingToken.IsCancellationRequested)
            {
                using (var scope = _scopeFactory.CreateScope())
                {
                    var dbContext = scope.ServiceProvider.GetRequiredService<NautilusDbContext>();

                    Console.WriteLine("[IncomingEthTxService] Service is Running");

                    // Run something

                    await Task.Delay(5, stoppingToken);
                }
            }
        }
    }

Если вы заметили, там есть бонус. Вам понадобится сервисная область для доступа к операциям с БД, потому что она одиночная.

Введите ваш сервис в

// Background Service Dependencies
            services.AddSingleton<IHostedService, IncomingEthTxService>();
0 голосов
/ 08 сентября 2018

это просто недоступно в .NET Core 2.0?

Метод ServiceCollectionHostedServiceExtensions.AddHostedService (IServiceCollection) , как показано в справочнике API

Относится к
ASP.NET Core
2.1

Однако исходный код доступен на GitHub.Вы можете легко проверить это там и скопировать локальную версию в ваш проект 2.0

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionHostedServiceExtensions
    {
        /// <summary>
        /// Add an <see cref="IHostedService"/> registration for the given type.
        /// </summary>
        /// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to register with.</param>
        /// <returns>The original <see cref="IServiceCollection"/>.</returns>
        public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services)
            where THostedService : class, IHostedService
            => services.AddTransient<IHostedService, THostedService>();
    }
}

Исходный код

В идеале вы можете просто обновить проект до версии 2.1, гдерасширение становится доступным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...