dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.35k stars 9.99k forks source link

Error injecting custom class in to startup constructor #26191

Closed chandimar001 closed 4 years ago

chandimar001 commented 4 years ago

I have a simple ASP.Net Core 3.1 test project. I created an interface named ITestClass and a class named TestClass that implements it.

I register this interface with DI in program.cs using ConfigureService().

namespace AspNetCoreStartupDI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                    .ConfigureServices(services => services.AddSingleton<ITestClass>(new TestClass()))
                    .UseStartup<Startup>();
                });
    }
}

I then pull in TestClass in to the startup constructor through DI.

namespace AspNetCoreStartupDI
{
    public class Startup
    {
        private ITestClass TestClass;

        public Startup(IConfiguration configuration, ITestClass testClass)
        {
            Configuration = configuration;
            this.TestClass = testClass;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }
}

I get the following exception at runtime saying that ITestClass couldn't be resolved. Unable to resolve service for type 'AspNetCoreStartupDI.Models.ITestClass' while attempting to activate 'AspNetCoreStartupDI.Startup'.

What am I doing wrong? Pretty sure it is something obvious.

Pilchie commented 4 years ago

See https://github.com/aspnet/Announcements/issues/353

ghost commented 4 years ago

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

chandimar001 commented 4 years ago

Thanks for the quick response @Pilchie. While this wasn't a solution it definitely was the root cause (this is by design).

My scenario requires a DI container to be instantiated as singleton during startup so that it can be used in startup.cs in conjunction with the ApplicationStarted and later accessed by other parts of the code.

I accomplished this by registering the DI container in ConfigureServices() (along with other DI registrations) and setting the variable in Configure(). The variable didn't HAVE to be set in the startup constructor.

        public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicationLifetime, ITestClass testClass)
        {
            this.TestClass = testClass;
            applicationLifetime.ApplicationStarted.Register(this.OnStarted);
            applicationLifetime.ApplicationStopping.Register(extendShutdown => this.OnShuttingDown((bool)extendShutdown), !this.hostingEnvironment.IsDevelopment());

            app.UseResponseCompression();
            app.UseRequestContextMiddleware();
            app.UseTelemetryMiddleware();
            app.UseCors();
            app.UseMvc();
        }