The Daily Parker

Politics, Weather, Photography, and the Dog

D is for Database

Blogging A to ZWelcome to day 4 of the Blogging A-to-Z challenge. After yesterday's more theoretical post on the CLR, today will have a practical example of how to connect to data sources from C# applications.

Almost every application ever written needs to store data somewhere. If you're deploying a .NET website into Microsoft Azure (like this blog), you will probably connect it to an Azure SQL Database. Naturally, Visual Studio and C# make this pretty easy.

Here's the code that opens up a database connection and prints out to the Trace window what it's opened:

#region Copyright ©2018 Inner Drive Technology

using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;

#endregion

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
	public static class DataConnections
	{
		private static string ConnectionString => ConfigurationManager.ConnectionStrings["Database"].ConnectionString;

		public static void Connect()
		{
			using (var connection = new SqlConnection(ConnectionString))
			{
				connection.Open();
				Trace.WriteLine($"Connected to {connection.DataSource}");
			}
		}
	}
}

Let's take a look at that line by line.

Lines 3-6 tell the compiler that the objects referenced in the executable code come from those four namespaces (which I'll talk more about on April 16th). The SqlConnection class, for example, lives in the System.Data.SqlClient namespace. If I didn't have the using statement on line 5, I'd have to reference the class and its namespace as System.Data.SqlClient.SqlConnection, which is cumbersome.

Line 13 creates a ConnectionString property that gets its value from a configuration setting. More on that below.

Line 17 first sets up a different kind of using statement, which makes sure that whatever the expensive SqlConnection class does while its alive, it gets cleaned up when it finishes on line 21—even if it throws an exception. Then the same line creates a new SqlConnection object and assigns it to the variable connection.

Line 19 attempts to open the connection to the database. If it succeeds, line 20 prints out the name of the data source. If it fails, it throws an exception that whatever method called this one can catch.

The configuration file looks like this (but with a real database, user ID, and password):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<connectionStrings>
		<add 
			name="Database" 
			connectionString="server={server name}.database.windows.net;initial catalog={database name};persist security info=True;user id={user ID};password={password};"
		/>
	</connectionStrings>
</configuration>

Notice that the name on line 5 corresponds to the configuration setting name on line 13 of the C# code. That's how the code knows which connection string to read from configuration.

Finally, there's also a unit test, which looks like this:

#region Copyright ©2018 Inner Drive Technology

using InnerDrive.DailyParkerAtoZ.WeekOne;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace InnerDrive.DailyParkerAtoZ.UnitTests
{
	[TestClass]
	public class DataConnectionsTests
	{
		[TestMethod]
		public void CanConnectToDataSource()
		{
			DataConnections.Connect();
		}
	}
}

If the call to DataConnections.Connect() succeeds, the test passes. If the call fails, the test fails and shows the exception that gets thrown.

You can download the code for all of these posts here. You'll have to change the configuration information in the unit test project's app.config file to make it work, of course.

Parker post-surgery update

Whew. Parker is just fine.

The surgeon said everything went very well. She reported he completely tore his meniscus and his right CCL (the doggy equivalent of a human's ACL), and it looked like the result of an acute injury, not age-related deterioration. This is good news because it means he has a much lower risk of doing this to his left leg than we worried about.

He's recuperating from the operation right now and will remain overnight for observation. He should be home after lunch tomorrow, with a healthy quantity of drugs and probably a really sharp appetite.

Recovery should take 6-8 weeks, though he should be able to go for actual walks within about 2 weeks. But wow, he's not going to like those two weeks.

Stay tuned. Photo tomorrow, I expect.

Parker update: surgery today

Parker did not have a good morning.

I woke him up early, then "forgot" to feed him, and wouldn't even let him lick the cream cheese off my knife when I had a bagel right in front of him. All he got was an unpleasant-tasting amino supplement and a pain pill.

He did get a ride in the car, though, which might have gotten his mind off his appetite.

But then he got unceremoniously carried up two flights of stairs (the elevator at the pet hospital was out of order) and handed off to someone who smelled like frightened cats.

Let's not even talk about the thunderstorms forecast for later today.

So, Parker is chilling at the hospital right now, with his surgery scheduled for this afternoon. Because he's in the late group, I won't get to visit him tonight, which is probably OK because that might just upset him. He should be ready to go home tomorrow late morning.

I'll post again when the surgeon calls after the operation.

C is for Common Language Runtime

Blogging A to ZDay 3 of the Blogging A-to-Z challenge brings us to the heart of .NET: the Common Language Runtime (CLR).

Microsoft defines the CLR as the run-time environment which "runs the code and provides services that make the development process easier." That isn't the most helpful definition, so let me try to elaborate.

As I described Sunday and yesterday, the .NET compiler takes your source code from C# or whatever other language you use and compiles it down to one or more managed modules containing intermediate language (IL), which get further compiled into assemblies.

When your program runs, the CLR is the thing running it. It loads your assemblies and then handles all the tasks your program needs to survive, like memory management, thread synchronization, exception handling, security, etc. It actually does this through Just-in-Time compilation (JIT), when it translates the IL into your machine's own language. This means that when an IL instruction is executed for the second time, it runs in native CPU code.

The CLR also manages .NET's common type system (CTS), which "defines how types are declared, used, and managed in the common language runtime," according to Microsoft. Types (my topic for April 23rd) are therefore a part of every .NET program, even (gasp!) Ruby.NET. I'm picking on Ruby because in that language, ever instruction gets interpreted at run time, making it possible to use types that you haven't defined. The CLR and the CTS prevent you from doing that.

To learn a lot more about the CLR, I strongly recommend Jeffrey Richter's CLR via C#, which I mentioned Sunday.

Canine User Experience

Yesterday, the Nielsen Norman Group released groundbreaking research on user interface design for dogs:

There are several key usability guidelines that help dogs to have the most usable experience on modern websites and apps, particularly on mobile, tablet, and other touch-based interfaces:

  • Consistency is critical. While consistency in any user experience is important, with dogs, it’s even more so. Experienced dog trainers will tell you that, for dogs to learn proper behavior, consistency in enforcing routines, expectations, and commands is critical. Some common UI culprits that provide extra difficulty for dogs are swipe ambiguity, gestures without signifiers, tap uncertainty for flat UI elements like ghost buttons, and unusual placement of common elements like navigation and search.
  • Tap targets must be large. We recommend 1cm2 for human tap targets, but paws (whether belonging to cats or dogs) require larger tap sizes (of at least 3-4cm2, or even larger for Labradors and Great Danes).
  • Gestures must be ergonomic for dog physiology. While many wearable interfaces now involve gestures such as swiping left or right to dismiss notifications or switch apps, these need to be modified for more ergonomic canine movements (such as “shake”). Dogs have a greater ability to move paws with precision up and down, but dogs’ range of motion along the horizontal axis is limited and relatively imprecise, so all gestures must account for this limitation.

They also give special guidance on the risks of using hamburger menus and pie charts.

B is for BASIC

Blogging A to ZFor day 2 of the Blogging A-to-Z challenge, I'm going to talk about the first computer language I learned, which is still alive and kicking in the .NET universe decades after it first appeared on a MS-DOS 1.0 system disk: BASIC.

BASIC stands for "Beginner's All-Purpose Symbolic Instruction Code." The original specification came from John Kemeny and Thomas Kurtz at Dartmouth College in 1964. Today it's one of the core .NET languages included with Visual Studio as "VB.NET" (for "Visual BASIC," Microsoft's dialect of BASIC released in 1991).

Yesterday I showed you a "Hello, World" application written in C#. (You can download the source code here.)

Here's the VB.NET version:

Module Program

	Sub Main()
		Console.WriteLine("Hello, World!")
		Console.ReadKey()
	End Sub

End Module

What's different? Well, a lot of things: no braces, no include lines, no semicolon line endings...and that's just for a 2-line program.

But look at what's the same. Because this is a .NET program, the actual guts of it look almost exactly the same. There are two calls to different methods on the Console object, and except for the missing semicolons, they are identical to the calls in C#.

Here's the IL:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello, World!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

Wow. The IL is exactly the same. So both the VB.NET and C# code compile down to functionally identical assemblies.

And that's one of the most important characteristics of .NET: it lets you write code in any language you want (as long as someone has written a compiler for it), and run it on any platform you want (as long as there's a CLR for it).

I worked with Visual BASIC from versions 1 to 6, and then did one project in VB.NET before switching to C# in 2002. You really would need to pay me a lot of money to go back to it. I believe C# is more expressive, more concise, and more able to reflect my intentions than VB.NET.

But there is nothing wrong with VB.NET. If you want to use BASIC, enjoy. With the .NET ecosystem, it's up to you.

A is for Assembly

Welcome to the Daily Parker's 2018 Blogging A-to-Z challenge!

Blogging A to ZWe're starting today with a fundamental concept in Microsoft .NET software development: the Assembly.

Microsoft defines the assembly as "a .dll or .exe file that can contain a collection of APIs that can be called by apps or other assemblies." In other words, an assembly is the basic unit of delivering .NET software to the rest of the world. An assembly "fully describe[s] and contain[s] .NET programs."

When you compile .NET source code, the compiler creates one or more of these files, each of with contains an Intermediate Language (IL) representation of your original code. You can then distribute the .dll or .exe files to any computer that has the correct version of the .NET Common Language Runtime (CLR) installed on it.

I've created a Visual Studio solution for this challenge. Today we're looking just at one small piece of it, which looks like this:

using System;

// ReSharper disable CheckNamespace
namespace InnerDrive.DailyParkerAtoZ.HelloWorld
{
	internal static class Program
	{
		// ReSharper disable once UnusedParameter.Local
		private static void Main(string[] args)
		{
			Console.WriteLine("Hello, World!");
			Console.ReadKey();
		}
	}
}

If you're new to .NET, don't worry about all the pieces. This two-line program compiles into an assembly called HelloWorld.exe, which internally looks like this:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello, World!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

Again—we're not going to get into a lot here. Suffice to say, that IL above is what actually lives in the assembly, and what the CLR will execute when you run the program. The assembly also contains a manifest, describing what it contains, and some metadata about its version, author, and whatever else the programming team has added to the assembly info file.

As with all of the topics for this year's A-to-Z challenge, I'm only scratching the surface. There is a ton more to read online and in some solid books on the market. The best information about assemblies I've found is in Jeffrey Richter's CLR via C#.

Note: the Visual Studio Solution for this challenge requires Visual Studio 2017 and the .NET Framework v4.7. ReSharper is also recommended.

April come she will

Blogging A to ZThe A-to-Z Challenge starts tomorrow, and I'm all set to go with a list of 26 topics on programming with Microsoft .NET.

Now I just need to write the actual posts.

It's interesting to me how vacations don't actually lend themselves to much productivity, even when that's the explicit purpose of the vacation.

Anyway, if I do my job today, the first post will hit at noon UTC tomorrow. If I don't do my job today, it'll hit sometime later than that.

Still churning through my to-do list

On the one hand, I've been really productive on my staycation, having checked off 38 to-do items including a few that came from my need to get Parker repaired.

On the other hand, I've done none of the reading and writing I set out to do. With the A-to-Z challenge starting in two days, I really need to get on that.

But, you know, it's still a vacation. So why not vacate a bit?

The Thick of It is now

In a column last summer, UC Berkeley professor Ned Resnikoff saw Armando Ianucci's British sitcom The Thick of It as a warning:

As scathing as The Thick of It can be in its depiction of craven, self-interested political behavior, it’s difficult to imagine any of its protagonists engaging in criminality on a scale equal to what Trump’s inner circle may have committed.

Nor can The Thick of It capture the dizzying instability of American politics in 2017, though it has occasionally gotten close. The conventions of the sitcom genre usually demand that, for all the frantic activity in one episode or another, very little ever really changes; the prime minister might get ousted and the opposition may become the governing party, but the political system itself remains static. It’s barely five years later that we understand just how fragile that apparent stasis was all along.

Indeed, one can imagine a contemporary version of The Thick of It in which its starring hacks cross the murky boundary between unethical behavior and blatantly illegal acts,the usual unprincipled goons suddenly finding themselves locked into a partnership of convenience with committed racists; and in which the collateral damage they wreak has expanded to institutional and geopolitical dimensions. While that show does not yet exist, one can see the seeds of proto-Trumpian government-as-PR-crisis in old Thick of It episodes, like a warning we all failed to heed.

Yes. We're longing for the halcyon days of Malcolm Tucker. Welcome to the Trump Administration.