Skip to content

Instantly share code, notes, and snippets.

View rynowak's full-sized avatar
🤪

Ryan Nowak rynowak

🤪
View GitHub Profile

On Linkability and Size

Optimizing a .NET application for size requires us to develop new muscles, new tools, new designs, and new criteria for decision making. We typically provide customer value though building rich and powerful APIs. Optimizing for size asks something new of us, wanting granular APIs, uncoupled features, and statically-analyzable patterns.

Of the top ten non-Microsoft .NET library packages on nuget.org - 6/10 of these libraries serve the primary purpose of doing dynamic code invocation (IoC).

  • Newtonsoft.Json (Serializer)
  • Castle.Core (Reflection/IL utilities)
  • Moq (Mocking/Proxies/IL Generation)
  • Automapper (Object-Mapping)

API Template small single exe Roadmap

This document is a proposal for leveraging the learnings from the small-single-exe working group in ASP.NET Core in an immediately actionable way. All of these changes are aimed at improving one or more of the metrics that we're tracking for the single-effort without bad scenario takebacks.

There's still some design and scenario work to do here for ASP.NET Core - these aren't specs - the goal of this document to capture how we can apply learnings from this effort and accounting for what we stand to gain.

Executive Summary

We've completed the prototyping exercise, our primary results:

Summary

ASP.NET Core startup code follows regular patterns that are suitable for code analysis and enhancements to the coding experience through analyzers, code fixes, and smarter scaffolding.

What things that analyzers could provide would be most valuable?

Things that analyzers can easily understand:

  • What services are registered? (ex: AddMvc() includes AddRouting())
  • What options are set? (ex: AddMvcOptions(options => options.EnableEndpointRouting = false)
  • What middleware do you have? (ex: UseHealthChecks())

Bind cases

Option 0: (current state)

<input type="text" bind="@person.Name" />
<input type="text" bind-value="@person.Name" />
<input type="text" bind-value-oninput="@person.Name" />

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.

LOL What?

Allows you to write methods that contain mixed HTML and C# in Razor Views (.cshtml) / Razor Components (.razor) files.

This is a primitive for composing Razor code that is very low overhead / low concept. Your code calls your code.

In Views (not components): Can be async, can use tag helpers. In Components (not views): Usage and semantics still need figuring out, but we want to build something like this.

Sample

# Go paste this into http://viz-js.com/
digraph DFA {
0 -> 1 [label="/emojis"]
0 -> 4 [label="/events"]
0 -> 7 [label="/feeds"]
0 -> 10 [label="/gists"]
0 -> 80 [label="/issues"]
0 -> 83 [label="/markdown"]
0 -> 89 [label="/meta"]
@rynowak
rynowak / route_value_invalidation.md
Created June 7, 2018 19:33
Route Value Invalidation

Summary

Routing has a URL generation that feature that tries to make it simple and terse to generate URLs to related endpoints. This involves allowing ambient route values to be used in URL generation to obviate the need to re-specify them. Route value invalidation is the set of rules that govern the cases where routing can and cannot use the ambient values.

Example (Conventional Routing)

public class BlogController : Controller
{
 // Assume we just matched the route "{controller=Home}/{action=Index}/{id?}

Issues:

  • Partials used from overridable views need to go into Views/Shared or Pages/Shared in the app. Partials used from the app's layout also need to go into Views/Shared or Pages/Shared in the app. Using other search paths may work well until you start overriding things.

  • @namespace, @using and @addTagHelper are all problematic when it comes to copy-pasting code from a library into an app.

  • build-time errors for razor show up in errors window in VS, but clicking on them doesn't work.

We don't have a gesture to remove/hide a precompiled Razor assembly. Identity will need to disable its precompiled Razor assets by default. Without this feature the precompiled Razor Pages show up when areas are enabled (fails to resolve services) - and do not show up when areas are disabled.

Not Razor Related

Introduction to Razor Pages

Razor Pages is a new feature to ASP.NET Core MVC that makes coding page-focused scenarios easier and more productive.

Razor Pages is included in version 2.0.0 of ASP.NET Core. Tooling support for Razor Pages in Visual Studio ships in Visual Studio 2017 Update 3.

Getting Started

Razor Pages is on by default by MVC. If you are using a typical Startup.cs like the following, Razor Pages is already enabled.