Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Start Me Up: Configuration and DI in ASP.NET Core

Start Me Up: Configuration and DI in ASP.NET Core

Adoption of ASP.NET Core continues to grow in development shops around the world. The .NET community offers a nice selection of templates for getting a new project moving quickly. On the other hand, more complex applications may require you to go deeper than what comes out of the box. The configuration and dependency injection systems in ASP.NET Core are flexible and powerful, and it is worth understanding the details of how a modern web application on the framework spins up on start.

This session provides a walkthrough of the Startup and Program classes, the host and app builders, configuration, DI, and middleware. Learn how to build your own middleware providers and pipeline. Create custom extension methods to register services with your application quickly and easily. Leverage the power of ASP.NET Core to work best for you and your organization.

Jeff Strauss

October 01, 2019
Tweet

More Decks by Jeff Strauss

Other Decks in Programming

Transcript

  1. #startMeUp C O N F I G A N D

    D I I N A S P . N E T C O R E @ j e f f r e y s t r a u ss
  2. public class Program { public static Main(string[] args) { CreateWebHostBuilder(args).Build().Run();

    } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); } PROGRAM.CS
  3. public class Program { public static Main(string[] args) { CreateWebHostBuilder(args).Build().Run();

    } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); } PROGRAM.CS
  4. public class Program { public static Main(string[] args) { CreateWebHostBuilder(args).Build().Run();

    } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); } PROGRAM.CS
  5. 3.0

  6. public class Program { public static Main(string[] args) { CreateHostBuilder(args).Build().Run();

    } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args); } PROGRAM.CS
  7. public class Program { public static Main(string[] args) { CreateHostBuilder(args).Build().Run();

    } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } PROGRAM.CS
  8. <appSettings> <add key="ApplicationName" value="MyDemoApp" /> </appSettings> <system.webServer> <defaultDocument> <files> <add

    value="default.aspx" /> </files> </defaultDocument> </system.webServer> WEB.CONFIG
  9. ../MyDemo/ $ dotnet user-secrets list No secrets configured for this

    application. ../MyDemo/ $ dotnet user-secrets set "FooServiceSettings:ApiKey" "abcde12345" Successfully saved FooServiceSettings:ApiKey = abcde12345 to the secret store. CLI TOOLING
  10. 3.0

  11. new WebHostBuilder() .ConfigureAppConfiguration((builderContext, config) => { config.AddJsonFile("settings.json") .AddXmlFile("config.xml", optional: true)

    .AddInMemoryCollection( Dictionary<string,string> ) .AddCommandLine(args) }) .UseStartup<Startup>(); PROGRAM.CS
  12. // assuming IConfiguration is injected as _config _config.GetValue<string>("Setting1"); // "Value1"

    _config.GetValue<string>("FooServiceSettings:ApiKey"); // "abcde12345" DEMOCLASS.CS
  13. // assuming IConfiguration is injected as _config _config.GetValue<string>("Setting1"); // "Value1"

    _config.GetValue<string>("FooServiceSettings:ApiKey"); // "abcde12345" var section = _config.GetSection("FooServiceSettings"); section.GetValue<int>("Timeout") // 60 DEMOCLASS.CS
  14. public class FooServiceSettings { public string Url { get; set;

    } public string ApiKey { get; set; } public int Timeout { get; set; } public bool Persist { get; set; } } FOOSERVICESETTINGS.CS
  15. // assuming IConfiguration is injected as _config var options =

    new FooServiceSettings(); var configSection = _config.GetSection("FooServiceSettings"); DEMOCLASS.CS configSection.Bind(options);
  16. // options: {FooServiceSettings} // ApiKey [string]: "abcde12345" // Persist [bool]:

    false // Timeout [int]: 60 // Url [string]: dev-api.fooservice.nl DEMOCLASS.CS configSection.Bind(options);
  17. public class Startup { public void ConfigureServices(IServiceCollection services) { //

    optionally register services here... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // register middleware and build HTTP pipeline here... } } STARTUP .CS
  18. public class Startup { public void ConfigureServices(IServiceCollection services) { //

    optionally register services here... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // register middleware and build HTTP pipeline here... } } STARTUP .CS
  19. public interface IFooService { void Connect(); List<int> GetFoos(); } IFOOSERVICE.CS

    public class FooService : IFooService { public void Connect() { // ... } public List<int> GetFoos() { // ... } } FOOSERVICE.CS
  20. STARTUP .CS public class Startup { public void ConfigureServices(IServiceCollection services)

    { services.AddScoped( typeof(IFooService), typeof(FooService) ); } }
  21. STARTUP .CS public class Startup { public void ConfigureServices(IServiceCollection services)

    { services.AddScoped<IFooService>( new FooService( args ) ); } }
  22. services.AddMvc(); )b ); STARTUP .CS public class Startup {a public

    void ConfigureServices(IServiceCollection services) {a }a }a
  23. 3.0

  24. public static class FooExtensions { public static IServiceCollection AddFoo( this

    IServiceCollection services, string logPath) { services.AddSingleton<IFooFactory, FooFactory>(); services.AddScoped<IFooService, FooService>(); services.AddSingleton<IFooLogger>(sp => new FooLogger(logPath)); return services; } } FOOEXTENSIONS.CS
  25. public static class FooExtensions { public static IServiceCollection AddFoo( this

    IServiceCollection services, string logPath) { services.AddSingleton<IFooFactory, FooFactory>(); services.AddScoped<IFooService, FooService>(); services.AddSingleton<IFooLogger>(sp => new FooLogger(logPath)); return services; } } FOOEXTENSIONS.CS
  26. public static class FooExtensions { public static IServiceCollection AddFoo( this

    IServiceCollection services, string logPath) { services.AddSingleton<IFooFactory, FooFactory>(); services.AddScoped<IFooService, FooService>(); services.AddSingleton<IFooLogger>(sp => new FooLogger(logPath)); return services; } } FOOEXTENSIONS.CS
  27. public static class FooExtensions { public static IServiceCollection AddFoo( this

    IServiceCollection services, string logPath) { services.AddSingleton<IFooFactory, FooFactory>(); services.AddScoped<IFooService, FooService>(); services.AddSingleton<IFooLogger>(sp => new FooLogger(logPath)); return services; } } FOOEXTENSIONS.CS
  28. STARTUP .CS public class Startup { public void ConfigureServices(IServiceCollection services)

    { services.AddMvc() .AddFoo( path ) .AddDbContext(...) .AddIdentity(...) } }
  29. Middleware 1 Middleware 2 Middleware 3 // inbound logic await

    next(); // inbound logic // inbound logic // outbound logic // outbound logic // outbound logic Request Response await next();
  30. Middleware 1 Middleware 2 Middleware 3 // inbound logic await

    next(); // inbound logic // inbound logic // outbound logic // outbound logic // outbound logic Request Response await next();
  31. Middleware 1 Middleware 2 Middleware 3 // inbound logic await

    next(); // inbound logic // inbound logic // outbound logic // outbound logic // outbound logic Request Response
  32. app.UseHttpsRedirection(); if (env.IsDevelopment()) {a app.UseDeveloperExceptionPage(); }a else {a app.UseHsts(); }a

    STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {a }a
  33. app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMvc(routes => {a routes.MapRoute( "default", "{controller=Home}/{action="Index"}/{id?}"); }); else

    {a app.UseHsts(); }a STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {a }a
  34. app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMvc(routes => {a routes.MapRoute( "default", "{controller=Home}/{action="Index"}/{id?}"); }); else

    {a app.UseHsts(); }a STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {a }a
  35. app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( "default", "{controller=Home}/{action="Index"}/{id?}"); }); else

    { app.UseHsts(); } STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {a }a
  36. STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {

    app.Run(async (context) => { // do some logic on the context await context.Response.WriteAsync("I'm done!"); }); }
  37. STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {

    app.Use(async (context, next) => { // do some inbound logic on the request await next(); // do some outbound logic on the response }); }
  38. STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {

    app.UseHttpsRedirection(); app.Use(async (context, next) => { // do some inbound logic on the request await next(); // do some outbound logic on the response }); app.UseStaticFiles(); }
  39. public async Task Invoke(HttpContext context) {a private readonly RequestDelegate _next;

    public FooMiddleware(RequestDelegate next) {a _next = next; }a public class FooMiddleware {b }b FOOMIDDLEWARE.CS
  40. public async Task Invoke(HttpContext context) {a // do some inbound

    logic on the request await next(); // do some outbound logic on the response }a }a public class FooMiddleware {b }b FOOMIDDLEWARE.CS
  41. FOOMIDDLEWAREEXTENSIONS.CS public static class FooMiddlewareExtensions {b public static IApplicationBuilder UseFoo(

    this IApplicationBuilder app) { return app.UseMiddleware<FooMiddleware>(); } }b
  42. STARTUP .CS public void Configure( IApplicationBuilder app, IHostingEnvironment env) {

    app.UseHttpsRedirection(); app.UseFoo(); app.UseStaticFiles(); }
  43. W H E R E T O G O F

    R O M H E R E dig deeper