OdeToCode IC Logo

New Pluralsight Play by Play Featuring Visual Studio Live Share

Tuesday, April 2, 2019 by K. Scott Allen

Everyone should try Visual Studio Live Share. I only had to try the tool once to realize that any other screen sharing and meeting software was not going to be as good as VS Live Share (which works in VS Code, too).

Brice Wilson and I put together a Pluralsight Play by Play on Visual Studio to coincide with today’s launch of Visual Studio 2019. It’s a quick video with loads of demos, including how to use shared terminals and cooperative debugging of both C# and Node JS programs.

Play by Play Preparation

I hope you enjoy it, and the next time you want to work on a piece of code with other developers, try VS Live Share!

.NET Core Opinion 12 – Use Your ASP.NET Core App as an Executable

Wednesday, March 27, 2019 by K. Scott Allen

There is a special moment of time in the life of every ASP.NET Core process when the application has all the services registered and all the configuration sources in place, but has not yet started to listen for HTTP messages. This is a moment in time you can seize and use to your advantage.

I tell people to think of their ASP.NET Core application as a console application that happens to listen for network connections, because there are many useful tasks the application can perform at development time and in production. Examples would be tasks like migrating database schemas, clearing a distributed cache, and creating storage containers.

public static void Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    // the moment in time when magic can happen
    ProcessCommands(args, host);

    host.Run();
}

Let’s drill into database migrations. Many people will say we need to keep automatic migrations out of web applications because the results in a server farm are unpredictable. Good advice! I’m not suggesting you implicitly run migrations as a side-effect of the first HTTP request. I’m promoting the use of the application to explicitly run migrations when the app receives the right command line parameter. Think of the parameter as an automation point, and you can now migrate a database from a deployment script, or from a development shell.

Another objection is how executing utility tasks in the application feels like a violation of the single responsibility principle at the application level. Why not build a separate console application to execute utility tasks and leave the main app for processing web requests? This is possible, but you’ll find yourself needing to reuse or duplicate configuration code from the web application. Using database migrations as a concrete example again, there is a lot of work that goes into building the right services and configuration for a specific environment, including non-trivial steps like connection string decryption and network communication with key storage services. The app, assuming it works, is setup perfectly to have everything in place for a specific environment like production, staging, or development.

Here’s another example of something I’ve done in the past. On this project I could run the following command to drop the development database, recreate the database using migrations, seed the database with data, and then exit instead of entering into web server mode.

dotnet run  dropdb migratedb seeddb stop

The overall theme here is not about database specific tasks, but about automating common tasks to make development, testing, and deployments faster and more repeatable. The perfect tool for these jobs might just be the application you are already have!

.NET Core Opinion 11 – Keep Configure Methods Clean Using Extension Methods

Monday, March 25, 2019 by K. Scott Allen

The Configure and ConfigureServices methods in ASP.NET Core tend to become bloated in larger projects. The problem is that larger projects can require lots of configuration, and the configuration requires lots of options. You open a project and there are dozens, even hundreds of lines of code, to configure OIDC, Swagger, authorization policies, data services, claims transformations, cookie options, CORS policies, domain services, and the list goes on and on.

I encourage team members to use extension methods so each line of code in the Configure methods is simple and the configuration details are hidden (yet easy to find by navigating with F12).

For example, instead of using lambdas and overwhelming the reader with lots of configuration details ...

public void ConfigureServices(IServiceCollection services)
{

    services.AddMvc(options =>
    {
        options.Conventions.Add(new FeatureControllerModelConvention());
    })
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Clear();
        options.ViewLocationFormats.Add(@"{3}\{0}.cshtml");
        options.ViewLocationFormats.Add(@"Features\Shared\{0}.cshtml");
        options.ViewLocationExpanders.Add(expander);
    });

    // and more code and more code and more code
}

... Provide a high-level overview of the app configuration, but keep the details encapsulated.

public void ConfigureServices(IServiceCollection services)
{
    services.AddCustomMvc();
    services.AddSecurity();
    services.AddCustomMediator();
    services.AddDataStores(Configuration.GetConnectionString(nameof(LeagueDb)));
}

Hide the configuration details in extension methods which are easy to find.

public static IServiceCollection AddCustomMvc(this IServiceCollection services)
{
    var expander = new FeatureViewLocationExpander();

    services.AddMvc(options =>
     {
         options.Conventions.Add(new FeatureControllerModelConvention());
     })
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Clear();
        options.ViewLocationFormats.Add(@"{3}\{0}.cshtml");
        options.ViewLocationFormats.Add(@"Features\Shared\{0}.cshtml");
        options.ViewLocationExpanders.Add(expander);
    });

    return services;
}

There’s also a good chance you can re-use some of the extension methods, particularly in a micro-services environment. However, the primary focus is to make the startup code usable and readable, not re-usable.

Microsoft Watches GitHub Commits for Azure Secrets

Thursday, March 21, 2019 by K. Scott Allen

One morning last month I woke up, looked at my inbox, and saw:

Cyber Defense Opereations Center

I must admit, my first instinct when seeing any email with the word cyber in a 24 point font is to banish the message into a spam bucket, but something kept me around long enough to follow a link to GitHub. Lo and behold! Here was a connection string with the username and password to an Azure SQL instance using a familiar naming convention. To make a long story short, yes, someone outside the company accidentally checked in some test code with a connection string into a public repository.

There are many stories to tell here, but one story is another angle on the evolution of Microsoft. There was a time when the company shipped the world’s largest target for viruses and malware with no protection from viruses and malware installed. We were left to protect ourselves. The plan worked well for developers and other software savvy individuals, but not so well for the average user. Microsoft is now more aggressive and proactive about security, which is good for everyone.

One additional piece of information. Alerts like the one shown here are obviously important. But, by default the alert only goes to the subscription owner. You can change this setting in the portal by going into Security Center and opening the Security Policy blade. In the policy blade you'll see a list of subscriptions each with a link to configure settings. Click on the link and you can then go to Email notifications and configure a group email address.

Cyber Defense Opereations Center

Hope that helps!

The Lost Art of Right Aligning Code

Tuesday, March 19, 2019 by K. Scott Allen

When I started working with the Go language using Visual Studio Code a few months ago, the Go extension for VS Code auto-formatted one type definition like so:

type ResourceInfo struct {
    ResourceID         string
    SubscriptionID     string
    GroupName          string
    Name               string
    Type               string
    RunID              string
    DocumentType       string
    Location           string
    LocationMisAligned bool
}

When I was a C / C++ developer I created and read right-aligned code all the time. The alignment makes patterns in code easier to find. For another example in Go, it’s easier to see which entries point to a "no-operation" function in the following hash map, because you can scan vertically down the file.

var resourceMap = map[string]func(*ResourceInfo) {
    "Microsoft.Sql/servers":           visitSQLServer,
    "Microsoft.Sql/servers/databases": noop,
    "Microsoft.Cache/Redis":           visitRedisCache,
    "Microsoft.Web/sites":             visitWebSite,
    "Microsoft.Portal/dashboards":     noop,
    // ...
}

Keeping code aligned requires some work, and without tool support it is rare to see the convention in .NET languages. The only tool I've found that comes close to supporting this style is the Always Algined extension for Visual Studio.

.NET Core Opinion 10 – Move More Code Out of Startup

Thursday, March 7, 2019 by K. Scott Allen

In a previous opinion, we looked at the responsibilities of the Startup class in ASP.NET Core. A consistent problem I run across in code reviews is the amount of code that gravitates into the Startup class, making the entire file cluttered and not well factored.

We’ll look at a variety of solutions to declutter Startup.cs, but let’s start with a simple task. Once we agree that the Startup class is only responsible for service configuration and middleware, we should move other code out of Startup and into Program.cs where the Main entry point lives. Ironically, it is the .NET Core templates that I believe encourage cluttered and mismatched code inside of Startup.cs, but Microsoft has been improving these templates with each release. For example, here’s the startup code generated by dotnet new in 1.1.

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

// ...

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
                               ILoggerFactory loggerFactory)
{

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

         // ...
}

Notice how the code is configuring the configuration system in the constructor, and is configuring the logging settings in the method responsible for installing middleware. New templates in 2.1 remove these bits of code. Some of the code has moved into WebHost.CreateDefaultBuilder, but even if you need custom settings for configuration or logging, I’d suggest keeping the code out of Startup, and place the code into Program.cs instead.

As an example, here’s what Program.cs could look like, if it took on configuration and logging settings.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost
                .CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    var env = hostingContext.HostingEnvironment;
                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                    // ...
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                    // ...
                })
                .UseStartup<Startup>();

Look at extension methods for IWebHostBuilder and see what else you can move into Program.cs. In the next opinion post, we’ll talk about techniques for getting rid of the other clutter in the Configure* methods of Startup.

Debugging .NET Builds with the MSBuild Structured Log Viewer

Tuesday, March 5, 2019 by K. Scott Allen

I was trying to debug a dotnet publish operation on an ASP.NET Core project recently and becoming irrational after staring at MSBuild log files for too long. MSBuild does all the heavy lifting in dotnet publish and build operations. That’s when I discovered the MSBuild Structured Log Viewer from Kirill Osenkov. You can install the viewer from http://msbuildlog.com/.

In the end I was fighting a battle over $(DefaultItemExcludes) during publish and trying to find the right target to override and "fix" the property. Even the simplest builds are complicated these days, with implicit imports for .prop files, hundreds of properties, and dozens of tasks. Trying to figure the order of execution by looking at individual .csproj and .targets files is impossible.

MSBuildLog provides a tree view of all the targets that are executing, and provides the properties and items in effect for each step. The search feature is excellent and usually the best way to navigate into the tree, if you have an idea of what you are looking for. MSBuildLog Tree View

The tool also provides a list of the slowest build tasks, which these days always has Exec tasks calling out to Node or npm at the top of the list.

MSBuildLog slowest tasks