Tuesday, March 13, 2018

Visual Studio Code

I've been using VS Code for a while and I absolutely love it for all of my front-end editing needs. However, there are some shortcuts that I got used to in Visual Studio over the years that are different in VS Code. Fortunately, there's a way to easily rebind shortcuts in VS Code. Listed here are a few of my favorite changes to make to VS Code to get it setup the way I like it.

To change key bindings go to File > Preferences > Keyboard Shortcuts. Once in there you can search for the action and then double-click on it to change the binding. Below is a table with the default VS Code bindings, their corresponding Visual Studio bindings (if applicable), and the action taken. I change all of these before I do anything else in VS Code.

Action VS Code (Default) Visual Studio (Default)
Fold All Ctrl+k, 0 Ctrl+m, Ctrl+o
File: Save All Ctrl+K, S Ctrl+Shift+s 
File: Save As... Ctrl+Shift+s

I found that in recent versions you have to remove the binding for File: Save As... for the new File: Save All binding to work. Just right-click on the existing binding and choose Remove Keybinding in the context menu.
I also like to turn off the little preview pane that is displayed by default on the far right of the main window. To do that, go to View > Appearance > Minimap.

I'll update the table above as I find more shortcuts that don't match (I'm sure there are plenty). As usual, this list is more for me than it is anyone else so if it doesn't help you... make your own.

Monday, December 18, 2017

(My Distaste for) Coding Tests

I've been interviewing for about a month and as part of that process I was recently asked to do Fizzbuzz on a whiteboard and... it did not go well. I was not initially asked to do Fizzbuzz; I was asked how I would make it testable. The conversation went something like this:

Interviewer (I): How would you make Fizzbuzz testable?
Me: All code is inherently testable so I'm not sure I understand your question.
I: The way most people solve Fizzbuzz it is not testable. How would you do it differently?
Me: If the way most people solve Fizzbuz isn't testable then they're solving it wrong because - again - all code is inherently testable.
I: OK. Solve Fizzbuzz on the whiteboard.
Me: I'm not doing Fizzbuzz.
I: *perplexed look on his face* I just want you to show me how you would make Fizzbuzz testable.
Me: OK. *starts writing for loop on whiteboard and stops* I'm not going to write out a solution to Fizzbuzz. You'd basically make it testable by assigning the value ("Fizz", "Buzz", "Fizzbuzz", or the number) to a variable, injecting a logger class, and checking whether that logger class was called with particular parameters.
I: Can you be more specific?
Me: Not really. This isn't a difficult problem so it isn't a difficult solution.

As you can see, the interview got out of hand quickly. Since that day (about two weeks ago) I've been beating myself up for how everything happened and I've come to a few realizations that I want to share.

First and foremost, asking senior software engineers to solve a "problem" like Fizzbuzz is insulting. I have samples of my code freely available on Github and would gladly have written a small application on a computer to satisfy whatever coding requirements they have. Fizzbuzz is a test that should - at best - be given to developers who just finished school to see whether they can actually code.

I'm really conflicted on whether I think they should have just not asked me or I should have just answered. Ultimately, I think it's both. They shouldn't have asked that question, but when they did, I should have answered it. It wouldn't have been difficult to just write out a solution to Fizzbuzz on the whiteboard that was unit testable. I let me ego get the best of me ("You want me to do what?!") and it ended up costing me an opportunity.

Hopefully I've learned from this mistake and I won't react the same way in the future.

Sunday, December 17, 2017

It's Not What You Say, It's What You Say

In November I got the unpleasant news that my office was going to close in 2018. On the plus side, the company gave us almost two full months' notice so we could start getting our resumes up-to-date and looking for work. I've received a couple of offers, but neither of them really felt like the right opportunity for me. One was easy to identify the issues because they were quantifiable (think money, benefits, etc.), but the other was a little trickier.

I went through the full interview process with a medium-sized publicly traded company and I liked almost everything I heard. They used the latest technologies, they had a fun atmosphere, they provided games and drinks and snacks, everybody was really cool, and so on and so on. However, multiple times in the interview they indicated that they are available to work 24/7. The recruiter tried to clarify that they work a pretty standard schedule, but the gut feeling I had remained and I couldn't shake it.

This interview process revealed to me that it's not necessarily what you say, but it's also what you say. What I mean is that during the interview process they told me - I felt in no uncertain terms - that I would need to live and breathe the company if I came on board. That's fine for some people, but that's now what I'm about so it wouldn't have worked for me. Even though they tried to clear it up, even their clarification continued to tell me what I had previously heard.

Ultimately, I might be missing out on a great opportunity, and that would suck. But I'd rather miss out on a company than ignore my gut instinct that says this isn't the right place for me.

Update: I've had a few friends go to work for this company and my suspicions were correct. On top of the 24/7 availability, they have few to no processes (which is a big problem for me). I can confidently say 5 years later that declining this offer was the right move for me.

Tuesday, November 21, 2017

JavaScript Array.Filter

Several times in the recent past I've had a need to grab certain objects from an array based on a value of one of their properties. In Linq in C# I'd do something like this:
filteredItems = allItems.Where(i => i.FirstName == "Mickey");

In TypeScript I don't have Linq functions so I need an alternative when I'm writing Angular. Fortunately, JavaScript includes the Array.prototype.filter function that works very similarly. When I want to do the exact same thing as above, but in JavaScript (and therefore in TypeScripe) I'd do this:
filteredItems = allItems.filter(i => i.FirstName === "Mickey");

Did I say they were similar? Because they're pretty much identical. I'm sure I'll be revisiting this post many times in the future.

Saturday, November 11, 2017

All About Interfaces

I was recently asked for some good reading material on the difference between implementing and injecting interfaces and I couldn't come up with anything. I know the root cause of the lack of material is that the two concepts are totally different, but they are related so it's worth discussing them together.

First let's look at what an interface is in object-oriented programming. The simplest way to think of interfaces is as contracts. If you hire a crew to paint your house you're going to sign a contract with them. You've defined in the contract exactly which parts of the house need to be painted, the color of the paint in each area, and perhaps some small improvements to be done as they paint. When the painter agrees to take on the job, he's agreeing to implement that contract exactly as you specified.

An interface in programming is exactly the same as the contract we had the painter agree to. If we define an interface we're saying that any classes that want to agree to (implement) that interface must be structured exactly as the interface specifies. Let's take our painting example virtual and define our contract as an interface.
   1:  public interface IBindPainters
   2:  {
   3:      List<Improvement> Improvements { get; set; }
   4:  
   5:      Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      void Improve(Improvement improvement);
   8:  
   9:      void Paint(House house);
   10:  }

Any painter classes we create that want to implement (agree to) this interface (contract) must have a property called Improvements, a property called Colors, and methods called Improve and Paint. The signatures of the methods and types of the properties must also match the interface. So if we create a class called JohnPainter that wants to implement this interface it would at least look like what you see below.
   1:  public class JohnPainter : IBindPainters
   2:  {
   3:      public List<Improvement> Improvements { get; set; }
   4:  
   5:      public Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      public void Improve(Improvement improvement)
   8:      {
   9:          // do improvements around the house
   10:     }
   11:  
   12:     public void Paint(House house)
   13:     {
   14:         // paint the house
   15:     }
   16:  }

If we create a class called FrankPainter that wants to implement this interface, it would at least look like what you see below.
   1:  public class FrankPainter : IBindPainters
   2:  {
   3:      public List<Improvement> Improvements { get; set; }
   4:  
   5:      public Dictionary<Location, Color> Colors { get; set; }
   6:  
   7:      public void Improve(Improvement improvement)
   8:      {
   9:          // do improvements around the house
   10:     }
   11:  
   12:     public void Paint(House house)
   13:     {
   14:         // paint the house
   15:     }
   16:  }

Both of those classes implement the interface, which means that both John and Frank have agreed to our contract. That's literally all interfaces are for! An interface doesn't specify how the work gets done - Frank and John might each paint that house using completely different processes - and it doesn't actually do anything. It just guarantees that whoever implements the contract agrees to the terms.

So the next question that usually comes up is Why? Why do we use interfaces at all? Well, let's keep moving forward with the house painting example we've been using and see if we can answer that question, too.

As the homeowner, I know how the process of having my house painted is going to work. I'm going to hire a painter, give them the colors to paint each part of the house, show them the improvements that need to be made, have them do the improvements, then paint the house, then I'll pay them. Before I hire the painter, I can define my entire process, like this:
   1:  public class HomeOwner
   2:  {
   3:      private IBindPainters _hiredPainter;
   4:      private House _house;
   5:  
   6:      public HomeOwner(IBindPainters hiredPainter)
   7:      {
   8:          _hiredPainter = hiredPainter;
   9:         _house = new House();
   10:     }
   11:  
   12:     public void HaveHousePainted()
   13:     {
   14:         _hiredPainter.Colors = new Dictionary<Location, Color>();
   15:         _hiredPainter.Improvements = new List<Improvement>();
   16:         foreach (var improvement in _hiredPainter.Improvements)
   17:         {
   18:             _hiredPainter.Improve(improvement);
   19:         }
   20:  
   21:         _hiredPainter.Paint(this._house);
   22:     }
   23:  }

So what does this do for us? Well, we know that whatever painter we hire they're going to have to agree to our contract, so we can setup our entire day before we know who is going to actually paint the house. If we decide to hire Frank we just pass Frank as the painter into our constructor and everything works fine. If we decide to hire John we just pass John as the painter into our constructor and everything works fine.

Since our constructor is expecting an interface (IBindPainters) what it's really expecting is a class that implements that interface. Whether that class is John or Frank makes no difference to how we're going to have our house painter. Whoever we hire is going to have to agree to our contract.

This really comes in handy when we don't know ahead of time which class we'll get. Let's say I'm not the one picking the painter; it's my wife instead, but she can't be home when the painter shows up. She leaves me very clear instructions on what to do when the painter gets there (give him the colors and areas to paint those colors, show him the improvements, have him make the improvements, then have him paint), but she forgets to tell me who she hired. Well, it doesn't matter as long as the person who shows up agrees to the contract.

When the painter shows up - whoever it is - we just plug him into our predefined process and he gets to work. Guess what? That's what injecting an interface means! Injecting an interface just means we provide a class that implements the interface, but we depend on (expect) the interface instead of a specific class.

Let's recap.

  • An interface is just a contract; it cannot be instantiated itself
  • When a class implements an interface, it just means that class agrees to the terms of the contract
  • Injecting an interface means we expect a class that implements an interface to be provided
  • Interfaces do not actually do anything... ever!
Hopefully this helps you out if you've been trying to understand interfaces and/or injecting them.

Thursday, July 20, 2017

Unit Testing Web API when the Result is an Anonymous Object

Sometimes it seems like each day opens my eyes to some new challenge or trick.  If only I could find the time to write about them all.  Today I discovered you can return anonymous objects from a WebAPI controller.  Returning the data was actually the easy part, but being able to unit test it turned out to be a little bit tricky.

I found this answer on Stack Overflow, which pointed to this blog post by Patrick Desjardins that ultimately helped me figure out what needed to be done, but I wanted to document the actual steps I took to make this all work.

The scenario was that we had a custom object that had a bunch of properties on it.  Our UI needed all of that information plus one more field, but we weren't able to just add another property to our object because reasons (that part isn't important).  We also didn't want to create a brand new object to contain our original object plus this other field.  The obvious solution was to return an anonymous type from our controller.

Let's say our object is book and it has a couple of properties on it.  It looks like this:

   1:  public class Book
   2:  {
   3:      public string Author { get; set; }
   4:          
   5:      public string ISBN { get; set; }
   6:  }

When we return our object to the UI we also need to include a StoreId.  What we want to return will look like this:
{
  StoreId: 12345,
  Book: {
    Author: "Herman Melville"
        
    ISBN: "978-1853260087"
  }
}

What we ended up with was a controller method that looks like this:
   1:  [HttpGet]
   2:  public async Task<IHttpActionResult> GetBook()
   3:  {
   4:      var book = new Book
   5:      {
   6:          Author = "Herman Melville",
   7:          ISBN = "978-1853260087"
   8:      };
   9:   
  10:      var result = new {StoreId = 12345, Book = book};
  11:      return Ok(result);
  12:  }

In order to test this we have to do two things.  For starters let's say our Web API project is called Bookstore.Api and our unit tests are in a separate project called Bookstore.Api.UnitTests.  We need to modify the AssemblyInfo.cs file in Bookstore.Api to make internal types available to Bookstore.Api.UnitTests because the anonymous object we're returning from the GetBook method becomes an internal type when it's created.  To do this, just open AssemblyInfo.cs in Bookstore.Api and add this line (where it gets added doesn't seem to matter, but the name absolutely does matter):
[assembly: InternalsVisibleTo("Bookstore.Api.UnitTests")]

Important Note: In .Net Core 2.0 (at least) you have to create the AssemblyInfo.cs file manually as it is no longer generated automatically when you create the file. I just expanded the Properties folder, right-clicked > Add > Class > AssemblyInfo.cs and added the above attribute as the only thing in the file. I did have to include the using statement for System.Runtime.CompilerServices as well.

Finally we can write our test to check the return value of the StoreId in our unit test:
   1:  [TestMethod]
   2:  public async Task GetBookShouldReturnStoreIdWithBook()
   3:  {
   4:      dynamic result = await bookController.GetBook();
   5:   
   6:      Assert.AreEqual(12345, result.Content.StoreId);
   7:  }

It's really important to use dynamic as the return type (as much as I hate doing that) because it's the only way the compiler won't make angry faces at you.  I hope this helps someone (or future me).

Monday, May 15, 2017

Microsoft Build 2017 - Part 1

I know I've been spending a lot of time talking about Angular 2 (or 4) lately, but last week I was afforded the opportunity to attend Microsoft's annual Build conference in Seattle and, boy was I impressed.  I want to take a few posts to tell the world (and remind myself) about all the cool stuff I saw.  And since this is my blog I'm going to do just that.

So let me start with the Day 1 Keynote.  Yes, it was 3-ish hours long and there was a lot that I felt could have been cut out, but there was a ton of information they put out there that blew me away.  I seriously watched parts of the keynote with my mouth hanging open.  It was embarrassing.  So what was so cool?  Well, let's start with the Azure Stack because I've been in situations where this particular technology would have solved issues that we weren't able to solve at the time.

Azure Stack

Azure Stack is all the stuff we know and love in Azure, but deployed to other servers.  I remember a couple of years ago I was interviewing for a senior developer role with a company that was all excited about switching to Azure because they "could deploy it wherever they wanted".  I didn't take that job primarily because of that fundamental misunderstanding of what Azure iswas.  If Azure Stack had been available then I'd have been laughed out of the room for explaining to the Director of IT that what he had described was impossible... and also that company would probably still be in business.  At any rate, there are a variety of reasons that companies have avoided switching to cloud-based solutions and Azure Stack solves a few of them.  The examples provided in the keynote all had to do with remote-based workers and non-connected branches (like cruise ships), but the first thing that came to my mind were government organizations.  On at least two occasions I've had first hand experience with government agencies being unable to use Azure in particular because of legal restrictions on where their data can be housed.  They had to be able to show at any given moment that all of their information was stored in a particular state or country.  With Azure Stack they'd be able to do that because they'd be managing the physical servers running Azure!  This is an incredible option now!

Furthermore, SaaS companies using Azure (like my current employer) this opens up a whole new area of opportunities.  We can now sell our products to companies that are unwilling or unable to shift to a cloud-hosted solution like Azure.  We can write our code once and use it in the cloud as well as make it available for those offline solutions.

Outside of the keynote I also checked in with the Azure Stack booth and confirmed that Azure Stack is literally all of the functionality of Azure, but portable to any data center or proprietary servers.  I also asked for confirmation that Azure Stack customers would be able to - but not forced - to update when a new version of the software is released, and that was confirmed.  That means that late adopters of SaaS products can exist if they use Azure Stack.  SO COOL!  (Yeah, I'm gonna nerd out on most of this stuff so just get used to it now.)

Azure IoT Edge

OK, I have to admit that while I thought the MS demo for this was pretty neat, I didn't immediately see a benefit of using it on anything I worked on.  From what I understand - and this is mostly based on the demo they showed - this basically allows us to offload some processing from the cloud to individual IoT devices.  That is pretty darn cool, especially when you're talking about latency potentially costing money.  If you have a device - and endpoint - that needs some telemetry to know when to change things (maybe slow down or speed up production based on something else happening down the line) you can export that telemetry to the device itself and save the latency.  In the case of the demo this potentially led to millions of dollars in savings if a machine shuts itself down before something goes terribly wrong.  Pretty cool stuff, but again I didn't see any immediate application for anything I'm working on.

Azure Browser CLI

This one was cool for an obvious reason, and a not-so-obvious reason.  First the obvious reason: DUDE, THEY PUT AN AZURE CLI IN THE FREAKIN' BROWSER!  C'MON, THAT'S AWESOME!  OK, so what that means is that now anyone who is more comfortable scripting their commands than using the Azure Portal can now use the CLI in the browser itself.  There's nothing to install and nothing to add; it's already live and it already works.  Very cool for keyboard jockeys like me.

OK, so the not-so-obvious reason: they did it in bash... from Linux.  And what's more is they said during the presentation that basically "we'll get to doing it in Powershell eventually".  That's HUGE.  All my life Microsoft has taken the stance of "Windows first, second, and forever" and everything else can go suck a lemon.  When they have ported some stuff to other platforms in the past it's always been 1) a port, and 2) usually missing some features.  This time around they basically said "Linux does this pretty well so we're gonna start there and if the Powershell team decides they want to implement a Powershell version they can later".  That is simply an amazing turnaround and I could not possibly love it more.

Azure Portal Mobile App

This was another one that I didn't see an immediate use for, but I know several of the guys (sadly, yes, all guys because we do have a gender issue in technology) around me got very excited when this came up.  The app brings the Azure Portal to our devices so we can... do Azure Portal stuff on the go, I guess?  I can see this being useful if you're in DevOps and\or you're administering things from the portal frequently.  In my day-to-day I don't need to do this so while I see that it is cool, it really isn't that cool for me.

Visual Studio for Mac

I won't lie to you. I am 100% not excited about this one.  I mean, don't get me wrong, I know some Mac people and they're pretty OK.  My wife was a Mac person before I converted her.  But I don't know any developers who prefer Visual Studio who also prefer Macs.  I'm sure they exist, but I don't know any.  And I'm not one (I just don't care for Mac's OSs).  So it's not that this isn't exciting, it just isn't exciting for me.

I will say that I heard some pretty bad reviews from people who used the beta version of this so even if I was a Mac person I'm not sure I'd be too thrilled about this.

PowerPoint Translator

I don't think this feature got enough love in the keynote because frankly it's amazing.  As a side job I used to teach adults how to use computers.  I taught them everything from what a computer is through using Access.  I speak English and Spanish, but I still couldn't reach all of my students.  If I'd had PowerPoint Translator back then I could have reached more people.  Not many more, but more.  I've also talked to some friends of mine who are trainers in similar areas and they are very excited about this technology.

Just having the ability to provide closed captioning in another language as you speak is... well, it's amazing is what it is.  It's not the Universal Translator from Star Trek, but holy cow it's a huge step in the right direction.  I know we have things like Google Translate and Facebook has a translation feature, but this puts all of the power of a translation service directly into PowerPoint presentations with very little additional work - and no technical know-how - from the trainer.  I know there are corporate applications as well, but the first thing that struck me was the ability to reach more people with important information, like training immigrants how to use computers to find work.

Cortana

When I told my brother about all the cool stuff they were showing with regards to Cortana he said "Cortana needs to die". I tried to convince him that what I was seeing was really cool, but he didn't want to hear it.  I hope he comes around and at least looks into it because it really is really cool.  What do I mean?  I'm glad you asked!

Let me start by asking you this: did you know Cortana was available on iOS and Android devices?  You did?  Well... way to steal my thunder then... jerk.  I didn't.  Right off the bat, that's pretty cool.  I know iOS has Siri and Android has... whatever you call it when you say "OK, Google" and it does stuff, so this is just one more voice-activated AI-ish type deal you can have on your phone.  However, with Cortana on your devices you can actually integrate all of your stuff better.  And you can create new "skills" (yeah, I think it's a stupid term for it, too) for Cortana to learn to do stuff for you.  So let's say your company produces a SaaS for finding picnic baskets in Jellystone Park.  You can write a bot (more on that later, maybe not in this post, but definitely later) that then interacts with a Cortana skill so you can have users say to their phone "Cortana, ask Yogi where to find the closest picnic basket".  And with that, Cortana can check with your bot and return information however you deem most appropriate.  The demo from the keynote is pretty cool, but I don't think they did a good job of separating Microsoft Teams (which I think is also new, but I wasn't entirely sure) from Cortana's capabilities.  They also didn't do a great job differentiating between the bot and the Cortana skill so I had to do some more digging.

At the Cortana Skills booth is where I learned about bots and a little bit more about skills.  Basically the bot does the heavy lifting and can be integrated into lots of different channels besides Cortana.  But Cortana gets to do some of the fun stuff when you write a skill.  The booth guy was helpful, but ultimately it sounded like I needed to learn more about bots.  Then I went to the Cortana Skills presentation on day 2 and got even more information.  I hope that presentation gets posted to Channel 9 because it was actually really helpful to watch a developer write a skill and deploy it.  He showed us in the demo how we can change Cortana's output to include things like a card in the search results (similar to what Bing does right now if you search for something).  Cortana isn't just voice activated, but it is intended to be primarily voice activated so you have to consider that as well.  All-in-all I saw some pretty neat applications for some things I'm working on now and in the near future.

OK, this post has gotten a bit out of hand.  I'm not even through the whole keynote yet and I feel like I've written a novel.  I'm gonna wrap this one up here and try to add another one tomorrow.  I have a lot more to cover and some of the really cool stuff is yet to come, not to mention the fact that I haven't even touched on the Day 2 Keynote.  Man, it was a packed 3 days.