13

I have a strange occurrence happening in a brand new .net core 2 web app. This is the standard web api from the template built into Visual Studio. VS 2017, all the jazz. Here's the the entire startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using VerySimpleAPI.Helpers;

namespace VerySimpleAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddHostedService<MainLoop>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc(routes => {
                routes.MapRoute(
                    name: "Default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index"}
                    );
            });
        }
    }
}

MainLoop implements IHostedService and IDisposable.

The services.AddHostedService<MainLoop>(); does not resolve, producing the error "'IServiceCollection' does not contain a definition for 'AddHostedService' and no extension method..." all that jazz. I checked out the Microsoft.Extensions.DependencyInjection source, and I clearly see the definition for public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services)

Without the hosted service reference, the project compiles just fine. Is there something I'm missing?

3
  • 1
    AddHostedService is part of Microsoft.Extensions.Hosting.Abstractions. While it is defined in the Microsoft.Extensions.DependencyInjection namespace, it belongs to Microsoft.Extensions.Hosting.Abstractions in the ServiceCollectionHostedServiceExtensions class
    – Nkosi
    Commented Jul 9, 2018 at 15:18
  • @Nkosi adding using Microsoft.Extensions.Hosting; and using Microsoft.Extensions.Hosting.Abstractions; does nothing. I can clearly see the the definition for AddHostedService here: github.com/aspnet/Hosting/blob/master/src/…
    – Nomenator
    Commented Jul 9, 2018 at 15:23
  • Yep exactly the same source I linked to.
    – Nkosi
    Commented Jul 9, 2018 at 15:25

1 Answer 1

16

AddHostedService is part of Microsoft.Extensions.Hosting.Abstractions.

While it is defined in the Microsoft.Extensions.DependencyInjection namespace, it belongs to Microsoft.Extensions.Hosting.Abstractions in the ServiceCollectionHostedServiceExtensions class

using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;

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.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, THostedService>());

            return services;
        }
    }
}

And ensure that the relevant packages are installed and referenced to have access to the extension method

10
  • 1
    Good find, I'm glad you showed the source, I could of sworn hosted services were added as singletons +1
    – johnny 5
    Commented Jul 9, 2018 at 15:26
  • This is the source I originally turned to, when encountered that problem. using Microsoft.Extensions.Hosting; does nothing. There's something else missing.
    – Nomenator
    Commented Jul 9, 2018 at 15:34
  • @Nomenator Are you referencing the necessary libraries?
    – Nkosi
    Commented Jul 9, 2018 at 15:35
  • @Nkosi Good question. Apparently, Microsoft.Extensions.Hosting and Microsoft.Extensions.Hosting.Abstractions were not installed as nuget packages. I assumed they were available, since using Microsoft.Extensions.Hosting did not complain about not having a definition. Apparently, now we can use packages which are not installed. I had to drop using Microsoft.Extensions.Hosting because `'IHostingEnvironment' is an ambiguous reference between 'Microsoft.AspNetCore.Hosting.IHostingEnvironment' and 'Microsoft.Extensions.Hosting.IHostingEnvironment``
    – Nomenator
    Commented Jul 9, 2018 at 15:51
  • @Nomenator, Have you resolved the issue? I have the same problem. I am on core 2.0. Interesting to note, ServiceCollectionHostedServiceExtensions.AddHostedService is applied to .NET Platform Extensions 3.1 3.0 2.2 2.1 only. It seems like it is not available in 2.0.
    – armyllc
    Commented Feb 6, 2020 at 17:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.