Skip to content

Instantly share code, notes, and snippets.

@rynowak
Last active August 12, 2020 15:46
Show Gist options
  • Save rynowak/4d4738a57fb482952056ca67573f1d50 to your computer and use it in GitHub Desktop.
Save rynowak/4d4738a57fb482952056ca67573f1d50 to your computer and use it in GitHub Desktop.

Routing in the small

ASP.NET Core 3.0 adds new some infrastructure that makes programming in the small (few methods/classes) more convenient.

These scenarios feel more immediate when you can use local functions, and it really benefits from being able to place attributes on them. In particular, placing attributes on parameters is one of the only ways we can provide expressiveness about where the arguments should come from (injecting a DbContext from services in my example).

Using lambdas is an option as well, but for many of these cases the user wants to explicitly specify the types, so it's a small jump in complexity to a local function.

I'm not sure which of these we'd pick stylistically for our samples/blogs - but I'm sure some users will want to do this and it's come up during our internal discussions. I wanted to pass on the feedback about this feature, we have a concrete use case for it.

Before

    public class Startup
    {
        ...
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting(routes =>
            {
                routes.Map("/", SayHello);
                routes.Map("/secret", AdminsOnly);
            });

            app.UseAuthentication();
            app.UseAuthorization();
        }

        Task SayHello(HttpContext context)
        {
            return context.Response.WriteAsync("Hi there!");
        }

        [Authorize(Roles = "admin")]
        Task AdminsOnly(HttpContext context, [FromServices] ApplicationContext db)
        {
            // get message from db and write it out
        }
    }

With attributes on local functions

    public class Startup
    {
        ...
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting(routes =>
            {
                Task SayHello(HttpContext context)
                {
                    return context.Response.WriteAsync("Hi there!");
                }
                routes.Map("/", SayHello);
                
                [Authorize(Roles = "admin")]
                Task AdminsOnly(HttpContext context, [FromServices] ApplicationContext db)
                {
                    // get message from db and write it out
                }
                routes.Map("/secret", AdminsOnly);
            });

            app.UseAuthentication();
            app.UseAuthorization();
        }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment