If you have been working with previous versions of Visual Studio, you will find that Visual Studio 2019 definitely does not break the mold. What I mean to say is that Visual Studio 2019 feels much the same as previous versions, and that’s a good thing.
Visual Studio project types and when to use them
Managing NuGet packages
Creating project templates
Creating and using code snippets
Using bookmarks and code shortcuts
The Server Explorer window
Visual Studio Windows
Chapter 2 is actually an extension of Chapter 1 in many respects. Things that didn’t make it into Chapter 1 are being discussed in Chapter 2. I do believe, however, that these are essential to working with Visual Studio and will benefit developers in their day-to-day coding.
Visual Studio Project Types
Here you can start by grabbing code from GitHub or Azure DevOps, open a local Visual Studio project, open a local folder to edit code files, create a new project, or continue without code.
This allows you to quickly find what you are looking for.
Take note, though, that if you do not find what you are looking for, you may need to install a workload. To do this, click Install more tools and features. Refer to Chapter 1 to see how to use workloads in Visual Studio.
There are several project templates that you can choose from. Let’s see which ones there are and what project is suitable for specific situations.
Various Project Templates
Visual Studio 2019 has a whole host of project templates to choose from. I would even go as far as to say that it’s now even easier to find the template you need to use due to the filters in the Create a new project window. Let’s have a look at a few of these project templates net.
Console Applications
You will notice that this application is suited for running on Windows machines. But what if you need to run the Console Application across platforms such as Windows, Linux, and macOS? This is where .NET Core comes into play.
A few years ago (long before .NET Core was ever a thing), I needed to create an application that could be triggered on a schedule. The application’s executable would then be passed one of the several parameters that the application used to determine which database to connect to.
The application had to run without any user intervention to perform some sort of maintenance task. Due to the fact that no user intervention was needed, a Console Application best suited the use case. Be aware that a Console Application can accept user input, but for my purposes with this application, it was not necessary.
Windows Forms Application
It is important to note that Windows Forms apps built on .NET Core will still only be able to run on Windows and is not able to run on Linux or macOS.
This means that WPF and Windows Forms apps built on .NET Core will only run on Windows. There are no plans to make these application types cross-platform.
Why then use .NET Core for Windows Forms applications? Well, .NET Core applications are very, very fast. So it is well worth thinking about using .NET Core for Windows Forms applications.
It is possible to port Windows Forms applications to .NET Core 3.0. You will need to run a tool called the .NET Portability Analyzer to check if your application uses any APIs not currently supported in .NET Core. If it does, you will need to refactor your code to avoid those unsupported dependencies.
For a detailed step-by-step, refer to the Microsoft Developer channel on YouTube, and look for the video “How to Port Desktop Applications to .NET Core 3.0”. At the time of writing this book, the URL to this video was www.youtube.com/watch?v=upVQEUc_KwU.
Scott Hunter and Olia Gavrysh discuss this topic at the 7:56 minute mark.
Windows Service
Imagine that the application needs to monitor specific activity (be that in a database or file system) and then write messages to an event log. A Windows Service is perfectly suited for this purpose.
Windows Services have an OnStart method that allows you to define what needs to happen when the service starts. By definition, Windows Services are long-running applications that need to poll or monitor the system it runs on. To enable the polling functionality, you will need to use a Timer component.
A common mistake is to use a Windows Forms Timer for a Windows Service. You must ensure that you use the timer in the System.Timers.Timer namespace instead.
It is in this Elapsed event that you can write the code that your service needs to run in order to do what it needs to do.
Web Applications
As can be seen in the template description, these templates will allow you to create a regular Web Forms application, an MVC application or Web API application. If you need to run your application in a browser, then create an ASP.NET Web Forms or ASP.NET MVC application.
A Web API, on the other hand (sometimes also referred to as Web Services), is an application programming interface (API) that allows communication between various clients such as browsers, mobile devices, etc., and other software components such as a database. It can be used as a stand-alone application or as part of an ASP.NET Web Forms or MVC application.
Class Library
The last project template we will be looking at is the Class Library. It is worth noting that the Class Library will create a DLL that you can reuse in your applications. This is the purpose of a Class Library project.
There are many more project templates available in Visual Studio and are dependant on the workloads you have installed.
You might be wondering what the differences are between the various project templates. You will find a hint when you look at the tags. The Class Library running the .NET Framework will create a DLL that will only work on Windows machines.
The Class Library running .NET Core will create a library that will run on Windows, Linux, and macOS (it’s therefore cross-platform).
The Class Library running on .NET Standard will create a library that is guaranteed to run on all of the platforms supported in Visual Studio. The .NET Standard is a specification of all the APIs that work on all of the platforms. Therefore, if you create a Class Library on .NET Standard, it is guaranteed to run on desktop, mobile, Web, etc.
For more information regarding .NET Standard, have a look at the following article on Microsoft Docs: https://docs.microsoft.com/en-us/dotnet/standard/net-standard
There are many more project templates to choose from, and the project templates you see will depend on the workloads that you have installed. Explore some of the different workloads available to you, and see what project templates are available to you after installing a particular workload.
Managing NuGet Packages
As a software developer, being able to reuse code is essential to any modern development effort. In fact, being able to share code is the cornerstone of a healthy development community. There are many developers that create extremely useful code libraries that can add functionality to your particular application.
This is where NuGet becomes an essential tool for developers to create, share, and consume useful code. As a developer, you can package a DLL along with other required content needed for the DLL to function correctly, into a NuGet package.
Essentially, NuGet is just a ZIP file with a .nupkg extension that contains the DLLs you have created for distribution. Included inside this package is a manifest file that contains additional information such as the version number of the NuGet package.
Packages uploaded to nuget.org are public and available to all developers that use NuGet in their projects. Developers can, however, create NuGet packages that are exclusive to a particular organization and not available publicly. We will have a look at hosting your own NuGet feeds later on. For now, let’s have a look at how to use NuGet in your own Visual Studio project.
Using NuGet in Visual Studio
Developers can access NuGet right from within Visual Studio, but you can also browse www.nuget.org to find packages to use in your applications. In the following example, we will be using NuGet from within Visual Studio to add functionality to our ShipmentLocator application.
I have added a login form to the ShipmentLocator application as seen in Figure 2-15. What I want to do is encrypt the password typed in by the user and compare that to the encrypted password in the database.
As a rule, you should never be able to decrypt a password. If you can decrypt a password, then so can others that have more malicious intentions. After user registration, the encrypted password is stored in a database. Login requests are then encrypted and compared with the encrypted password in the database. If it’s a match, they are successfully authenticated.
You can definitely roll your own solution when it comes to encryption. Another route to take is to check NuGet to see if there are any solutions available that you can use.
The NuGet Package Manager screen provides a lot of information about the package you are going to install. The current version number is displayed, license information, project URL, as well as the author and download count for the particular package.
ValidateLogin method
The encrypted password is stored in the database. It is read in and stored in the storedEncrPassw variable. The clear-text password and the stored encrypted password are then validated. If validation succeeds, the user is logged in.
Remember, the code for this project is available on GitHub.
By adding a single NuGet package, we have added functionality to encrypt passwords, validate encrypted passwords, and encrypt and decrypt text using Rijndael, converting text to a SecureString object, reading the value from the SecureString object, and more. All this functionality has been added without having to write the logic ourselves.
This is the power that NuGet provides. It is definitely something you as a developer need to consider using if you do not already do so.
Hosting Your Own NuGet Feeds
Local feed – On a network file share
NuGet.Server – On a local HTTP server
NuGet gallery – Hosted on an Internet server using the NuGet Gallery project, you can manage users and features to allow searching and exploring available packages similar to nuget.org.
Azure Artifacts
MyGet – https://myget.org/
ProGet – https://inedo.com/proget
TeamCity – www.jetbrains.com/teamcity/
For a full list of NuGet hosting products and for more information on creating your own NuGet feeds, have a look at the following link on Microsoft Docs: https://docs.microsoft.com/en-us/nuget/hosting-packages/overview
Creating Project Templates
Sometimes developers create class libraries and code that they need to use over and over again across various new projects. What developers end up doing is copy and paste code into new class libraries. There is, however, an easier way to create projects that reuse code that you have previously written.
The Export Template Wizard is displayed as seen in Figure 2-23. This allows you to specify which template you need to create. The options are to create a Project template or to create an Item template. A Project template is what we are after in this example, but you can also create an Item template. This will allow you to add the code via the Add New Item dialog box in Visual Studio.
For this example, however, we keep the Project template option selected and select the project to export from the drop-down list. This drop-down lists all the projects in my Visual Studio solution. Select the ProjectUtilities project, and click the Next button.
Creating and Using Code Snippets
Code snippets in Visual Studio are small blocks of reusable code that you can insert into your code file by using a shortcut and tabbing twice or by using the right-click menu.
You can also hold down Ctrl+K, Ctrl+B to open the Code Snippets Manager window. Clicking each code snippet will display the description, shortcut, snippet type (expansion or surrounds with), and author. While some shortcuts are obvious (do, else, enum, for, and so on), others are not and might take some getting used to remembering to enter the shortcut and tabbing twice to insert the snippet.
You can also right-click and select Snippets and then Insert Snippet from the context menu. The last way that you can insert a code snippet is via the menu bar by going to Edit, IntelliSense and clicking Insert Snippet. Visual Studio also allows developers to create their own code snippets. Let’s have a look at that process next.
Creating Code Snippets
If there is one thing I wish, is that there was a nice interface baked into Visual Studio for creating and adding code snippets. Perhaps one day, but for now we have to do it the old-fashioned way.
Basic Snippet Template
Let’s assume that we have created a Custom project template that includes a logging class in our helper classes.
Refer to the previous section regarding Creating Project Templates.
Basic Logging Class
Custom Try-Catch Snippet
It is also worth noting that the code snippet might be XML, but the file extension must be .snippet for Visual Studio to be able to import it. If you refer back to Figure 2-28, you will notice an Import button on the Code Snippets Manager screen.
Click that button; browse for and import your newly created code snippet for the custom try-catch. You will notice that I have defined the shortcut as tryl for try-catch log.
This new code snippet is now available in all your future projects. Your C# code snippets live in the Documents folder in C:Users[USERNAME]DocumentsVisual Studio 2019Code SnippetsVisual C#My Code Snippets.
The code snippet schema reference is available on Microsoft Docs at the following link: https://docs.microsoft.com/en-us/visualstudio/ide/code-snippets-schema-reference?view=vs-2019
More often than not, you will be creating your own code snippets based off of an existing code snippet. This allows you to reuse functionality you know is working in the existing snippet and include it in your own.
Code snippets are definitely a very powerful productivity feature in Visual Studio.
Using Bookmarks and Code Shortcuts
At some point in your career, you will most likely be working on a very large code base. Do this for a while, and you will get bogged down with remembering where a specific bit of code is or where you need to go to get to a specific portion of logic.
Visual Studio can assist developers in bookmarking certain sections of code as well as adding shortcuts to other areas of code. Let’s have a look at what bookmarks and shortcuts are and when to use which.
Bookmarks
Let’s say that you are busy finishing up for the day, but just before you check in your code, you notice that there is some code that doesn’t look quite right. It is a method that has a single return statement and you know that you can use an expression body for methods.
You really don’t have the time to play around further because you have already passed the point that you needed to leave for home. So in order to not forget to have a closer look at this tomorrow, you decide to bookmark the method.
The bookmark is added to the side of the code editor and is indicated by a single black bookmark icon.
The Bookmarks window is displayed as seen in Figure 2-33. From the toolbar in the Bookmarks window, you can group bookmarks in folders, navigate between bookmarks, navigate between bookmarks in the current folder, toggle a bookmark on the currently selected line in code, disable all bookmarks, and delete bookmarks.
Now click the delete button on the Bookmarks toolbar. The bookmark is deleted without any confirmation from the user.
This is something I can sort of understand. Imagine how irritating it would be having to confirm every delete, especially when you want to remove only a subsection of bookmarks from your collection.
It is for this reason that I use bookmarks only as a short-term solution to remind me to go and perform some action in code or to refactor something I think needs refactoring.
For me, a bookmark is something I will come back to within the next day or so. Something I don’t want to put off doing. It is, therefore, a temporary placeholder to something I need to revisit.
But what if I wanted to go and add a more permanent pointer to some logic in code? This is where code shortcuts come in. Let’s have a look at this next.
Code Shortcuts
TODO Comment
This is a nice and quick method for adding reminders to your code so that you can easily refer to them and navigate to them by double-clicking the item in the Task List. You can, therefore, use the Task List to take you directly to the predefined location in code.
The comment marker, which is //
The predefined token (TODO in our example)
The rest of the comment
HACK
TODO
UNDONE
UnresolvedMergeConflict
These are by no means case sensitive and will appear in your Task List if following the form in Listing 2-5. You can also add your own custom tokens. Let’s see how to do that next.
Adding Custom Tokens
I like the idea of TODO to add items to my Task List, but I would also like to add a custom token to add an entry in my Task List that is a nice to have feature. Something that is less restrictive than a TODO, because that implies that this action must be completed.
I do not want to have a bunch of TODO entries for items that are simply nice to have features. For this reason, I want to add a custom token called NOTE that is simply a reminder to look at something, if and when I have the time.
Being able to add custom tokens in Visual Studio, as well as applying a priority to each, allows you to be very specific with comments that contain tokens. This way you can greatly increase the ease and efficiency of navigating through a large code base.
The Server Explorer
As the name suggests, the Server Explorer provides a quick and easy way of accessing servers. You can use it to test connections and view SQL Server databases or any databases that have the ADO.NET provider installed.
As seen in Figure 2-42, the Server Explorer offers access to Event Logs, Message Queues, Performance Counters, and Services on my local machine (MSI). It also provides access to my Azure subscriptions.
This will display a window allowing you to choose a data source as seen in Figure 2-43. You can connect to various types of data sources, but we are only interested in Microsoft SQL Server for now. Select that from the list and click Continue.
The next window (Figure 2-44) allows you to define your connection to the database. Here you need to specify the server name, the authentication type, and if SQL Server Authentication is selected, provide the username and password.
Create Table Statement
Modified Create Table Statement
This will now allow me to preview the database updates about to be applied as seen in Figure 2-48. If you do not want to let Visual Studio update the table, you can have it generate the script by clicking the Generate Script button. Alternatively, you can go ahead and click the Update Database button.
After the update is complete, you can see the results in the Data Tools Operations window as seen in Figure 2-49. From here, you can view the script as well as view the results.
Running SQL Queries
The Server Explorer also allows developers to run SQL queries, right from within Visual Studio. Go ahead and right-click a table (Figure 2-50), and click New Query from the context menu.
Take note that the context menu changes depending on what item you have right-clicked in the Server Explorer. When right-clicking a table, you will see items related to a SQL table. When right-clicking a View, you will see items specific to the View such as Show Results and Open View Definition. When right-clicking a Stored Procedure, the context menu will display the Execute command.
SQL Select Statement
If you are used to pressing F5 in SQL Server Management Studio, you might find yourself starting the Visual Studio debugger instead of running the query. I simply find it easier to click the run button and avoid my muscle memory faux pas.
Insert Statement
SQL Update Statement
While running SQL statements isn’t mind-blowing, it is very convenient being able to do all this without ever leaving Visual Studio. The Server Explorer definitely offers much more functionality than illustrated in this chapter. Dig around it a bit more, and see what the Server Explorer can do for your productivity.
Visual Studio Windows
I have often maintained that developers get stuck in a rut when it comes to working with Visual Studio. They tend to stick to what they know and keep on doing things that way until the cows come home.
Here are too many windows to discuss all in this chapter, but I will touch on two that I find very useful.
C# Interactive
How often have you wanted to test a small bit of code just to see if it works correctly? Well, with C# Interactive, you can do just that without having to debug your entire solution. Found toward the bottom of the View, Other Windows menu, C# Interactive is almost hidden. But gems usually are and you’re going to love using it if you don’t already.
Running a LINQ Query
C# Interactive is what we refer to as a REPL (Read-Eval-Print Loop). Being able to input expressions that are evaluated and results returned makes on the spot debugging possible in Visual Studio.
C# Interactive supports IntelliSense, so you get the same kind of editor experience as in Visual Studio. For a list of available keyboard shortcuts, REPL commands, and Script directives that C# Interactive supports, just type in #help and press the Enter key.
Code Metrics Results
The project that we have been using in this chapter is really not complex at all. It is really just to illustrate the concepts in this book. If you take a more complex project, one of the projects you have worked on at work, this next screen will look a lot different.
The image in Figure 2-56 are the results for the ShipmentLocator application we have been using throughout this chapter. It’s not really complex at all, so the metrics might seem all fine.
Please note that when you first open the Code Metrics Results screen, it will be blank. You need to click the Calculate Code Metrics for Solution button in the top left corner of the window.
Maintainability Index
Cyclomatic Complexity
Depth of Inheritance
Class Coupling
Lines of Code
The advantage of these metrics makes it possible for developers to understand what portions of code need to be worked on or more rigorously tested. It also allows developers to identify potential risks in their software. Ratings in this window are also color coded so that developers can quickly identify trouble spots.
Maintainability Index
This will be a value between 0 and 100 and represents how easy it is to maintain the code. The higher the value, the more maintainable your code is.
Cyclomatic Complexity
This metric measures the structure of your code and how complex it is. It uses the number of code paths it finds that flow through the program to calculate this score. A higher number indicates a complex control flow and is, therefore, harder to test and maintain. The numbers displayed in Figure 2-56 and Figure 2-57 are totaled for each project in the solution. Here it makes sense to expand the hierarchy and drill down to the individual methods to see where the problem areas lie.
Depth of Inheritance
As the name suggests, this metric measures the number of classes that inherit from each other. This goes all the way down to the base class. This means that a high number indicates a deep inheritance which is bad. This is because any changes to a base class have the potential to result in breaking changes further up in the derived classes. Here you will be wanting to see a lower score.
Class Coupling
Class Coupling basically measures how many classes a single class uses. Here, a high number is bad, and a low number is good. Class Coupling has been shown to accurately predict software failures. With a high coupling score, the maintenance and reusability of the class become really difficult because it depends on too many other types.
Lines of Code
The lines of code here are based on the count of the IL code. So this isn’t a true count of lines of code in the source file. Nevertheless, you will probably agree with me that a high count indicates that a lot is happening. Expanding the projects and viewing the code counts for individual methods will allow you to see which methods are trying to do too much. A high line count will indicate a method that is harder to maintain. Try to refactor these methods and simplify them.
Send Feedback
The Visual Studio team definitely takes feedback seriously. So much so that it drives much of what they do to improve Visual Studio.
You can now report a problem or suggest a feature right from inside Visual Studio 2019.
As a developer, we should take the time to report issues we come across. This can be anything from crashes to slow performance or something else unexpected.