Scott Hanselman

Exploring .NET Core's SourceLink - Stepping into the Source Code of NuGet packages you don't own

September 28, '18 Comments [13] Posted in DotNetCore | Open Source | VS2017
Sponsored By

According to https://github.com/dotnet/sourcelink, SourceLink "enables a great source debugging experience for your users, by adding source control metadata to your built assets."

Sounds fantastic. I download a NuGet to use something like Json.NET or whatever all the time, I'd love to be able to "Step Into" the source even if I don't have laying around. Per the GitHub, it's both language and source control agnostic. I read that to mean "not just C# and not just GitHub."

Visual Studio 15.3+ supports reading SourceLink information from symbols while debugging. It downloads and displays the appropriate commit-specific source for users, such as from raw.githubusercontent, enabling breakpoints and all other sources debugging experience on arbitrary NuGet dependencies. Visual Studio 15.7+ supports downloading source files from private GitHub and Azure DevOps (former VSTS) repositories that require authentication.

Looks like Cameron Taggart did the original implementation and then the .NET team worked with Cameron and the .NET Foundation to make the current version. Also cool.

Download Source and Continue Debugging

Let me see if this really works and how easy (or not) it is.

I'm going to make a little library using the 5 year old Pseudointernationalizer from here. Fortunately the main function is pretty pure and drops into a .NET Standard library neatly.

I'll put this on GitHub, so I will include "PublishRepositoryUrl" and "EmbedUntrackedSources" as well as including the PDBs. So far my CSPROJ looks like this:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
</Project>

Pretty straightforward so far. As I am using GitHub I added this reference, but if I was using GitLab or BitBucket, etc, I would use that specific provider per the docs.

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63127-02" PrivateAssets="All"/>
</ItemGroup>

Now I'll pack up my project as a NuGet package.

D:\github\SourceLinkTest\PsuedoizerCore [master ≡]> dotnet pack -c release
Microsoft (R) Build Engine version 15.8.166+gd4e8d81a88 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restoring packages for D:\github\SourceLinkTest\PsuedoizerCore\PsuedoizerCore.csproj...
Generating MSBuild file D:\github\SourceLinkTest\PsuedoizerCore\obj\PsuedoizerCore.csproj.nuget.g.props.
Restore completed in 96.7 ms for D:\github\SourceLinkTest\PsuedoizerCore\PsuedoizerCore.csproj.
PsuedoizerCore -> D:\github\SourceLinkTest\PsuedoizerCore\bin\release\netstandard2.0\PsuedoizerCore.dll
Successfully created package 'D:\github\SourceLinkTest\PsuedoizerCore\bin\release\PsuedoizerCore.1.0.0.nupkg'.

Let's look inside the .nupkg as they are just ZIP files. Ah, check out the generated *.nuspec file that's inside!

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>PsuedoizerCore</id>
<version>1.0.0</version>
<authors>PsuedoizerCore</authors>
<owners>PsuedoizerCore</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package Description</description>
<repository type="git" url="https://github.com/shanselman/PsuedoizerCore.git" commit="35024ca864cf306251a102fbca154b483b58a771" />
<dependencies>
<group targetFramework=".NETStandard2.0" />
</dependencies>
</metadata>
</package>

See under repository it points back to the location AND commit hash for this binary! That means I can give it to you or a coworker and they'd be able to get to the source. But what's the consumption experience like? I'll go over and start a new Console app that CONSUMES my NuGet library package. To make totally sure that I don't accidentally pick up the source from my machine I'm going to delete the entire folder. This source code no longer exists on this machine.

I'm using a "local" NuGet Feed. In fact, it's just a folder. Check it out:

D:\github\SourceLinkTest\AConsumerConsole> dotnet add package PsuedoizerCore -s "c:\users\scott\desktop\LocalNuGetFeed"
Writing C:\Users\scott\AppData\Local\Temp\tmpBECA.tmp
info : Adding PackageReference for package 'PsuedoizerCore' into project 'D:\github\SourceLinkTest\AConsumerConsole\AConsumerConsole.csproj'.
log : Restoring packages for D:\github\SourceLinkTest\AConsumerConsole\AConsumerConsole.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/psuedoizercore/index.json
info : NotFound https://api.nuget.org/v3-flatcontainer/psuedoizercore/index.json 465ms
log : Installing PsuedoizerCore 1.0.0.
info : Package 'PsuedoizerCore' is compatible with all the specified frameworks in project 'D:\github\SourceLinkTest\AConsumerConsole\AConsumerConsole.csproj'.
info : PackageReference for package 'PsuedoizerCore' version '1.0.0' added to file 'D:\github\SourceLinkTest\AConsumerConsole\AConsumerConsole.csproj'.

See how I used -s to point to an alternate source? I could also configure my NuGet feeds, be they local directories or internal servers with "dotnet new nugetconfig" and including my NuGet Servers in the order I want them searched.

Here is my little app:

using System;
using Utils;

namespace AConsumerConsole
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Pseudoizer.ConvertToFakeInternationalized("Hello World!"));
}
}
}

And the output is [Ħęľľő Ŵőřľđ! !!! !!!].

But can I step into it? I don't have the source remember...I'm using SourceLink.

In Visual Studio 2017 I confirm that SourceLink is enabled. This is the Portable PDB version of SourceLink, not the "SourceLink 1.0" that was "Enable Source Server Support." That only worked on Windows..

Enable Source Link Support

You'll also want to turn off "Just My Code" since, well, this isn't your code.

Disable Just My Code

Now I'll start a Debug Session in my consumer app and hit F11 to Step Into the Library whose source I do not have!

Source Link Will Download from The Internet

Fantastic. It's going to get the source for me! Without git cloning the repository it will seamlessly let me continue my debugging session.

The temporary file ended up in C:\Users\scott\AppData\Local\SourceServer\4bbf4c0dc8560e42e656aa2150024c8e60b7f9b91b3823b7244d47931640a9b9 if you're interested. I'm able to just keep debugging as if I had the source...because I do! It came from the linked source.

Debugging into a NuGet that I don't have the source for

Very cool. I'm going to keep digging into SourceLink and learning about it. It seems that if YOU have a library or published NuGet either inside your company OR out in the open source world that you absolutely should be using SourceLink.

You can even install the sourcelink global tool and test your .pdb files for greater insight.

D:\github\SourceLinkTest\PsuedoizerCore>dotnet tool install --global sourcelink
D:\github\SourceLinkTest\PsuedoizerCore\bin\release\netstandard2.0>sourcelink print-urls PsuedoizerCore.pdb
43c83e7173f316e96db2d8345a3f963527269651 sha1 csharp D:\github\SourceLinkTest\PsuedoizerCore\Psuedoizer.cs
https://raw.githubusercontent.com/shanselman/PsuedoizerCore/02c09baa8bfdee3b6cdf4be89bd98c8157b0bc08/Psuedoizer.cs
bfafbaee93e85cd2e5e864bff949f60044313638 sha1 csharp C:\Users\scott\AppData\Local\Temp\.NETStandard,Version=v2.0.AssemblyAttributes.cs
embedded

Think about how much easier consumers of your library will have it when debugging their apps! Your package is no longer a black box. Go set this up on your projects today.


Sponsor: Rider 2018.2 is here! Publishing to IIS, Docker support in the debugger, built-in spell checking, MacBook Touch Bar support, full C# 7.3 support, advanced Unity support, and more.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Tabs vs Spaces - A peaceful resolution with EditorConfig in Visual Studio. Plus .NET Extensions!

September 28, '17 Comments [23] Posted in VS2017
Sponsored By

The culture wars continue. The country is divided with no end in sight. Tabs or spaces? There's even an insane (IMHO) assertion that the spaces people make more money.

I'm going with Gina Trapani on this one. I choose working code.

Teams can fight but the problem of formatting code across teams is solved by EditorConfig. I'm surprised more people don't know about it and use it, so this blog post is my small way of getting the word out. TELL THE PEOPLE.

Take a project and make a new .editorconfig file and put this in it. I'll use a dotnet new console example hello world app.

[*.cs]
indent_style = tab
indent_size = tab
tab_size = 4

I've set mine in this example to just *.cs, but you could also say [*.{cs,js}] or just [*] if you like, as well as have multiple sections.

You'll check this file in WITH your project so that everyone on the team shares the team's values.

Here in Notepad2 we can see someone has used spaces for whitespace, like a savage. Whitespace appears as pale dots in this editor.

image

I'll open this project in Visual Studio 2017 which supports the EditorConfig file natively. Notice the warning at the bottom where VS lets me know that this project has conventions that are different than my own.

user preferences for this file type are overwidden by this project's coding conventions

VS Format Document commands will use tabs rather than spaces for this project. Here is the same doc reformatted in VS:

image

At this point I'm comforted that the spaces have been defeated and that cooler heads have prevailed - at least for this project.

.NET Extensions to EditorConfig

Even better, if your editor supports it, you can include "EditorConfig Extensions" for specific files or languages. This way your team can keep things consistent across projects. If you're familiar with FxCop and StyleCop, this is like those.

There's a ton of great .NET EditorConfig options you can set to ensure the team uses consistent Language Conventions, Naming Conventions, and Formatting Rules.

  • Language Conventions are rules pertaining to the C# or Visual Basic language, for example, var/explicit type, use expression-bodied member.
  • Formatting Rules are rules regarding the layout and structure of your code in order to make it easier to read, for example, Allman braces, spaces in control blocks.
  • Naming Conventions are rules respecting the way objects are named, for example, async methods must end in "Async".

You can also set the importance of these rules with things like "suggestion," or "warning," or even "error."

As an example, I'll set that my team wants predefined types for locals:

dotnet_style_predefined_type_for_locals_parameters_members = true:error

Visual Studio here puts up a lightbulb and the suggested fix because my team would rather I use "string" than the full "System.String.

Visual Studio respects EditorConfig

The excellent editorconfig for .NET docs have a LOT of great options you can use or ignore. Here's just a FEW (controversial) examples:

  • csharp_new_line_before_open_brace - Do we put open braces at the end of a line, or on their own new line?
  • csharp_new_line_before_members_in_object_initializers - Do we allow A = 3, B = 4, for insist on a new line for each?
  • csharp_indent_case_contents - Do we freakishly line up all our switch/case statements, or do we indent each case like the creator intended?
  • You can even decide on how you Want To Case Things And Oddly Do Sentence Case: pascal_case, camel_case, first_word_upper, all_upper, all_lower

If you're using Visual Studios 2010, 2012, 2013, or 2015, fear not. There's at least a basic EditorConfig free extension for you that enforces the basic rules. There is also an extension for Visual Studio Code to support EditorConfig files that takes just seconds to install although I don't see a C# one for now, just one for whitespace.


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

A proper terminal for Visual Studio

August 2, '17 Comments [30] Posted in VS2017
Sponsored By

Whack Whack Terminal is an experimental free plugin for Visual Studio 2017 that aims to bring a full terminal inside of Visual Studio. Those of you who use Visual Studio Code have long enjoyed the integrated xtermjs terminal. Justin Clareburt worked with Daniel Griffen on hacking together this solution as an experiment. There is no plans for it to be more than an experiment, I'm told BUT I always say vote with your feet. I figure a few tens of thousands of installs and someone will decide to build it in. I have long used Mads Kristensen's Quake Mode that lets me launch a command prompt from VS, but ever since the NuGet Package manager showed up in VS many years ago, I've always wanted a real FULL terminal in VS.

Today, the code is alpha quality, so expect it will actively improve, and don't be mean in the GitHub Issues. They've versioned it at 0.2, and is aiming for parity with the features in the terminal in VSCode for version 1.0.

Still, go install WhackWhack in VS2017 NOW! Nothing ventured, nothing gained!

Hey it's a real terminal inside of Visual Studio

I'm sure they will update it with lots of great features like changing the fonts and colors, but if you want to hack away (as of the date of this blog post) you can mess around in C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\sjogt3hc.qcl\daytona with ZERO WARRENTY EXPRESS OR IMPLIED. I went into there and edited the default.css file by removing all the comments and changing the background-color to black, the text to white, and adding a font-family choosing Consolas. If you do that, you'll likely need to uninstall/reinstall at some point when REAL customizations come. Again, alpha. But awesome.

"Whack" is a shorthand word for a slash (forward or otherwise) and the default hotkey is Ctrl+\, Ctrl+\. That's twice. so Ctrl WHACK WHACK. When you use the hotkey it will open the folder in the same folder as the currently selected project in the Solution Explorer.

If you want to change the hotkey to something else (like a more sensible Ctrl+~) you can do it in Tools | Options | Keyboard like this.

Changing the hotkey for the terminal

Then assign a new one by clicking in Press Shortcut Keys and typing "Ctrl+`" (which to me, is Ctrl ~ on my keyboard, without the shift)

Changing the hotkey for the terminal

By default the shell is PowerShell, but there's also places to support bash/Ubuntu, etc. For now, if you want bash, you can type C:\windows\sysnative\bash.exe in the terminal.

And just to freak you out, here's top running inside Visual Studio.

And just to freak you out, here's top running inside Visual Studio.

Enjoy! Install "WhackWhackTerminal" from here.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Visual Studio 2017 can automatically recommend NuGet packages for unknown types

March 24, '17 Comments [9] Posted in VS2017
Sponsored By

There's a great feature in Visual Studio 2015.3 and Visual Studio 2017 that is turned off by default. It does use about ~10 megs of memory but it makes me so happy that I turn it on.

It's under C# | Advanced in Tools Options. Or you can just type "Advanced" in the Quick Launch Bar (via Ctrl+Q if you like) to jump there.

I turn on "Suggest usings for types in NuGet packages" and "Suggest usings for types in reference assemblies."

I turn on "Suggest usings for types in NuGet packages" and "Suggest usings for types in reference assemblies."

For example, if I am typing some code and start referencing a Type that isn't in my project but could be...you know how sometimes you just need a using statement to bring in a namespace? In this Web App, I already have Json.NET so it recommends a using statement to bring it into scope.

Can't find JSON

But in this Console App, I have no packages beyond the defaults. When I start using a type like JObject from a popular NuGet, Visual Studio can offer to install Json.NET for me!

Find and install latest version

Or another example:

XmlDocument

And then I can immediately continue typing with intellisense. If I know what I'm doing, I can bring in something like this without ever using the mouse or leaving the line.

JObject is now usable

Good stuff! 


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test, build and debug ASP.NET, .NET Framework, .NET Core, or Unity applications. Learn more and get access to early builds!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

dotnet new angular and dotnet new react

February 13, '17 Comments [30] Posted in Javascript | Open Source | VS2017
Sponsored By

I was exploring the "dotnet new" experience last week and how you can extend templates, then today the .NET WebDev blog posted about Steve Sanderson's work around Single Page Apps (SPA). Perfect timing!

image

Since I have Visual Studio 2017 RC and my .NET Core SDK tools are also RC4:

C:\Users\scott\Desktop\fancypants>dotnet --info
.NET Command Line Tools (1.0.0-rc4-004771)

Product Information:
Version: 1.0.0-rc4-004771
Commit SHA-1 hash: 4228198f0e

Runtime Environment:
OS Name: Windows
OS Version: 10.0.15031
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\1.0.0-rc4-004771

I can then do this from the dotnet command line interface (CLI) and install the SPA templates:

dotnet new --install Microsoft.AspNetCore.SpaTemplates::*

The * is the package version so this is getting the latest templates from NuGet. I'm looking forward to using YOUR templates (docs are coming! These are fresh hot bits.)

This command adds new templates to dotnet new. You can see the expanded list here:

Templates                                     Short Name      Language      Tags
------------------------------------------------------------------------------------------
Console Application console [C#], F# Common/Console
Class library classlib [C#], F# Common/Library
Unit Test Project mstest [C#], F# Test/MSTest
xUnit Test Project xunit [C#], F# Test/xUnit
Empty ASP.NET Core Web Application web [C#] Web/Empty
MVC ASP.NET Core Web Application mvc [C#], F# Web/MVC
MVC ASP.NET Core with Angular angular [C#] Web/MVC/SPA
MVC ASP.NET Core with Aurelia aurelia [C#] Web/MVC/SPA
MVC ASP.NET Core with Knockout.js knockout [C#] Web/MVC/SPA
MVC ASP.NET Core with React.js react [C#] Web/MVC/SPA
MVC ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
Web API ASP.NET Core Web Application webapi [C#] Web/WebAPI
Solution File sln Solution

See there? Now I've got "dotnet new react" or "dotnet new angular" which is awesome. Now I just "npm install" and "dotnet restore" followed by a "dotnet run" and very quickly I have a great starter point for a SPA application written in ASP.NET Core 1.0 running on .NET Core 1.0. It even includes a dockerfile if I like.

From the template, to help you get started, they've also set up:

  • Client-side navigation. For example, click Counter then Back to return here.
  • Server-side prerendering. For faster initial loading and improved SEO, your Angular 2 app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over. THIS IS HUGE.
  • Webpack dev middleware. In development mode, there's no need to run the webpack build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.
  • Hot module replacement. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular 2 app will be rebuilt and a new instance injected is into the page.
  • Efficient production builds. In production mode, development-time features are disabled, and the webpack build tool produces minified static CSS and JavaScript files.

Go and read about these new SPA templates in depth on the WebDev blog.


Sponsor: Big thanks to Raygun! Join 40,000+ developers who monitor their apps with Raygun. Understand the root cause of errors, crashes and performance issues in your software applications. Installs in minutes, try it today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Page 1 of 2 in the VS2017 category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.