How to configure the DI services available to the launch class constructor

When I create a web host for the main ASP.NET application, I can specify the class Startup, but not the instance.

The constructor of the Startup native class can accept a parameter that is provided through the DI. I know how to register services for DI internally ConfigureServices, but since this is a member of this class, these services are not available to the constructor of my startup class.

How to register services that will be available as a parameter of the constructor of the Startup class?

The reason is because I have to provide an instance of an object that needs to be created outside / before the web host is created, and I don't want to pass it in a global style.

Code for creating IWebHost:

this.host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseIISIntegration()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseStartup<WebStartup>()
log.Debug("Run webhost");
this.host.Start();

Constructor WebStartup:

public WebStartup(IHostingEnvironment env, MyClass myClass)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddEnvironmentVariables()
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
        .Build();
    ...
}

, MyClass (, , , WebStartup IWebHost)?

+5
3

, , DI, .

ASP.NET Startup, ConfigureServices IWebHostBuilder:

var host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .ConfigureServices(services => services.AddSingleton<IMyService, MyService>())
    .UseStartup<Startup>()
    .Build();

host.Run();

public Startup(IMyService myService)
{
    myService.Test();
}

, , UseStartup<WebStartup> , IStartup DI (. ).

, , IServiceProvider. IServiceCollection Startup.

+9

" ": DI , .

, ( ASP.NET Core), , .

, , , . , .

. :

public class Startup
{
    private static MyDependency dependency;

    public Startup(IHostingEnvironment env)
    {
        dependency = new MyDependency();
        var instance = new MyClass(dependency);

        var builder = new ConfigurationBuilder()
            .SetBasePath(instance.ContentRootPath)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // Register the dependency if it is required by other components.
        services.AddSingleton<MyDependency>(dependency);

        // Add framework services.
        services.AddMvc();

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

    // etc.
}
+7

MyClass myClass Startup. , .

myClass myClass UseStartup:

var host = new WebHostBuilder()
    // .... other code
    .ConfigureServices(services => services.AddSingleton(myClass)) // Inject myClass instance
    .UseStartup<WebStartup>()

Startup ( - WebStartup). , , ConfigureServices() , , , Startup.Configure() . :

    // This goes into Startup.cs/WebStartup.cs
    public virtual void ConfigureServices(IServiceCollection services)
    {
        var myClass = services.Single(s => s.ServiceType == typeof(MyClass)).ImplementationInstance as MyClass;
        if (myClass == null)
            throw new InvalidOperationException(nameof(MyClass) + " instance is null");

        // Now do all the things
    }

, Framework - , - - , !

0

Source: https://habr.com/ru/post/1658706/


All Articles