Category Archives: Fritz and Friends

Stream Wrap Up – SignalR and Refactoring for Unit Testing Madness

The weekly scramble is over, and I think we accomplished a lot in building overlays and answering questions this week.  Let’s review the progress from this week’s streams:

We started with a question from djvortechs about referencing packages from Visual Studio extension projects, or VSIX’s.  After a little exploration, I couldn’t come up with the immediate answer.  In a follow-up discussion with Mads Kristensen on Twitter, he indicated that the package we were trying to reference, Newtonsoft.Json is distributed with Visual Studio and was not needed to be included in the redistributable VSIX package.

I started work on the Fritz.StreamTools project with a simple refactoring to centralize all references to sending a command to all attached SignalR clients.  This new FollowerClient class allowed me to write the “magic string” containing the SignalR client-side function name.

public class FollowerClient
{

  public FollowerClient(IHubContext<FollowerHub> followerContext)
  {

    this.FollowerContext = followerContext;

  }

  private IHubContext<FollowerHub> FollowerContext { get; }

  public void UpdateFollowers (int newFollowers) {

    FollowerContext.Clients.All
      .InvokeAsync("OnFollowersCountUpdated", newFollowers);

  }

}

The FollowerContext is a reference to the server-side Hub that our clients are listening on.  Whenever we need to update the follower count on attached clients, the UpdateFollowers method can send that new follower count to all clients that have a “OnFollowersCountUpdated” client-side method.

I then started writing a simple RazorPage to present the current viewers from both Twitch and Mixer services, with a goal to emulate the widget that currently resides in the top-right corner of the video.  This new page, CurrentViewers.cshtml, contains very similar markup to the Followers goal widget that I constructed previously.  I copied and pasted some of the Followers code to drive updating this new Current Viewers widget.


On Thursday’s stream, I ran into a brief GitHub outage… and that lead to some fun with chromakey and the GitHub pink unicorn error message.

Jeff is angry at the GitHub Unicorn

I now have a new error page template

Big thanks to Carey Payette for capturing that second pic of me during the stream as I was playing with the GitHub error page.

I started by adding a .EditorConfig file to the Fritz.StreamTools project to help enforce some standards in code formatting and syntax.  Additionally, I set the TreatWarningsAsErrors property in the project’s csproj file to true.  When the EditorConfig extension is in place in Visual Studio, it will throw errors during the build process if my rules are violated.  This should also help with ensuring that my files are formatted with my preferences, like preferring tabs over spaces.

Next, we looked at how I added a logger to the interactions with the Twitch and Mixer services.  This allows those services to report to the container’s logs when changes in the service state occur.

Next, I started using PowerShell to maintain the files committed to Git source control.  The module that I prefer to use with PowerShell for Git highlighting, tab-completion, and prompt enhancements is called posh-git.  It was really easy to install from the PowerShell command-line in Windows 10:

  1. PowerShellGet\Install-Module posh-git -Scope CurrentUser
  2. Import-Module posh-git
  3. Add-PoshGitToProfile

More details including permission configuration is available on the posh-git project page.

Next, I performed a refactoring where I moved the contents of the Startup.ConfigureServices method to another class in order to simplify the contents of the Startup class.  This is a very important class, and with the volume of content in it, the chances of inadvertently breaking something was starting to grow.  I simplified by creating a class in a folder called “StartupServices” called “ConfigureServices” that has a single method, Execute and would do the same things as the former Startup.ConfigureServices method.

I re-arranged the code in that Execute method, and even added some groupings by moving some of the similar configuration into private methods.  I think this now makes the configuration of services for this project a bit easier to manage, and defends the Startup class against invalid updates.  In the future, we can write some unit-tests against the ConfigureServices class to ensure that our configuration is being applied properly.

Then, we merged a pull-request from Bruno that rolled up the various streaming services into an aggregate StreamService object.  This was really great because all of the user-interface work in the project could be refactored to remove their direct references to Twitch or Mixer.  Really great stuff, and a good step towards making our code more testable.

I made my application a little bit easier to tweak and re-run by using the dotnet watch feature.  This was added to my project by adding the Microsoft.DotNet.Watcher.Tools reference to my project file and then executing on the command line “dotnet watch run”.  This would re-start the application whenever a server-side file changed on disk.

We updated the CurrentViewers razor page to take advantage of this new aggregate StreamService, and output the collection of services and viewer counts by using a simple Linq query.  Then, I received a comment in the chat room that suggested I use the JavaScript array reduce feature to update the total viewer count, instead of using a for..loop to sum the values.  This JavaScript code to sum the values for the Total Viewers element looks like:

const reducer = (accumulator, currentValue) => 
   accumulator + parseInt(currentValue.textContent, 10);
var currentCounts = document.getElementsByClassName("serviceCount");
var elArray = Array.from(currentCounts);
document.getElementById("totalCount").textContent = elArray.reduce(reducer, 0);

The reducer function receives an accumulator value and the currentValue that it should be operating on.  The currentCounts object is a collection of HTML elements with the CSS class “serviceCount”, and is converted to an array using the Array.from statement.  Finally, the totalCount textContent is set to the result value of the reducer function operating on each element of the elArray, with an initial accumulator value of 0.

Finally, I added a check to only add the Twitch and Mixer services when a ClientID is configured for those services.  With this indirect reference to these services in use now, we should be able to conditionally add services as they are configured.

On Saturday’s stream, we started by answering some questions about the new Span feature and also a question about how and where to get a comprehensive teaching experience online for .NET Core development. Of course, you can check out Microsoft Virtual Academy and the .NET Core courses that I have written as well as my book about Learning ASP.NET in 24 hours.

In this stream, I focused on adding unit tests to the solution.  My primary way of executing unit tests is in Visual Studio 2017, and I showed how to run tests manually and also the Live Unit Testing feature of the Enterprise edition of Visual Studio.  Also, I showed that the dotnet watch tool could be used for testing as well just by running “dotnet watch test” against my test project.

I started with some simple tests to verify that the count of followers and viewers was summed properly, and then moved on to testing the more complex interaction of verifying that the output from Twitch was handled properly by the application.

There were some questions about PHP and unit testing during the stream.  I suggested folks check out the Peachpie project, which enables PHP applications to be compiled with the .NET roslyn compiler.  Jakub Misek from the Peachpie project spoke about the features during dotNetConf 2017, and that video is below:

We then wrote some more complex tests to inspect the events raised when the Twitch service raises the Updated event. To do this, we used the xUnit event testing feature that looks like this:

var evt = Assert.Raises<ServiceUpdatedEventArgs>(
  h => sut.Updated += h,
  h => sut.Updated -= h,
  () => sut.Service_OnNewFollowersDetected(null, myArgs)
);

Assert.Equal(initialFollowers + newFollowerCount, evt.Arguments.NewFollowers);
Assert.Null(evt.Arguments.NewViewers);

The Raises method takes a type parameter that matches the arguments type of the Event we are looking for, attaches and detaches from the Updated event in the first two arguments, and the third parameter is the method call that should trigger the Updated event.  The return value from the Raises method is a wrapper around this Updated event that we can inspect on the last two lines of the sample.

Overall some good progress this week.  Next week, we’re going to start the week with completing the YamlConfigurationBuilder from the ConfigurationBuilders project.  Later, we should have a guest on Thursday or Saturday morning.  Keep an eye on the stream and my Twitter account for updates about the content planned this week.  I hope to see you then!

Live Stream Wrapup – Security, ASP.NET Core and SignalR

I’m a little late getting the wrapup blog posts together for this week’s streams, so I figured I would just pull them all into one MEGA-UPDATE.  It was a crazy week for me, with a LOT accomplished outside of the stream… I cleaned up my security mess with Amazon, and worked on some cool SignalR integration with our StreamTools project.

Continue reading

Stream Wrap-up: Personal Security and Renaming a Project

Today’s stream didn’t deliver much in terms of new code, but I think it had a bit of value.  Over the last 24 hours, my Amazon account was hijacked.  I started the stream discussing what happened as well as the steps I am taking to remedy it. Then, I fixed an issue with Epic Build Music, and then did the tedious renaming of the Rundown project.

Continue reading

Pair Programming and Algorithm Discussion with Iris Classon

Today’s stream was different from previous ones, as I had my second guest and we worked together to look at some code and discuss a tricky algorithm problem.  Microsoft MVP Iris Classon joined me and we discussed a very complex problem she is attempting to solve.

The problem we discussed and looked at surrounds the processing of various calculations.  The following rules are defined for these calculations:

  • A calculation depends on a parent calculation that it is defined with
  • A calculation can trigger zero to many other calculations
  • We need to minimize allocation of calculations, and the number of times a calculation runs
  • The calculation as currently defined have recursion, and we want to allow the recursion to execute at most 3 times, before stopping the recursion and outputting a warning message

This hierarchy of calculations is easy to manage with a dozen calculations… but now they have thousands and scale is a problem.  Watch the video above to see our discussion of this problem and see some of the pseudo-source code Iris wrote to test a potential solution.

I’m taking Tuesday off for the Christmas holiday, but will be back on Thursday.  Saturday the 30th I will be an in-arena announcer for my daughter’s horse show event, so I will not have a stream that day.  Join me again on Tuesday the 2nd for the next stream after that.