Search code examples
c#asp.net-core-3.1kestrel-http-server

How to pass some property on startup class and initialize it on controller


I have a .net core 3.1 background application where i am spanning kestrel server as per implementation. What i need is to initialize some property (let's say int channel id) when it is configured at startup

Startup

internal class Startup
{
    internal static IHostBuilder CreateHostBuilder(MyConfigurations _objSettings)
    {
    
        //_objSettings.channelId need to be assigned to CallBackController channelID
        return Host
            .CreateDefaultBuilder()
            .ConfigureWebHostDefaults(webBuilder => 
                webBuilder.UseUrls(_objSettings.CallbackLocalListener)
            )
            .UseStartup<Startup>());
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers(options => options.RespectBrowserAcceptHeader = true);
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseForwardedHeaders();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

Controller

[Produces("application/json")]
public class CallBackController : ControllerBase
{          
    int channelId = 0;//this need to be initializes 

    public IActionResult Receive()
    {
        IActionResult result = null;
       
        return result;
    }
}

I needed this as same class multiple instances will be starting kestrel instance on other ports listening different traffic. At the time of request receive i need that channel Id to initialize something


Solution

  • Create an type to store the desired options

    public class ChannelOptions {
        public int ChannelId { get; set; }
    }
    

    and configure that in Startup using the convivence members

    internal static IHostBuilder CreateHostBuilder(MyConfigurations _objSettings) {        
        return Host
            .CreateDefaultBuilder()
            .ConfigureServices(services => 
                services.AddSingleton(
                    new ChannelOptions {
                        ChannelId = _objSettings.channelID
                    }
                )
            )
            .ConfigureWebHostDefaults(webBuilder => 
                webBuilder.UseUrls(_objSettings.CallbackLocalListener)
            )
            .UseStartup<Startup>());
    }
    

    and finally, explicitly inject the options into the controller as a dependency

    [Produces("application/json")]
    public class CallBackController : ControllerBase {
    
        private readonly int channelId = 0;
    
        public CallBackController(ChannelOptions options) {
            channelId = options?.ChannelId ?? 0;
        }
    
        public IActionResult Receive() {
            IActionResult result = null;
           
            return result;
        }
        
        //...
    }