Waldo Codes

Pragmatic insights on software craftsmanship and other topics.

Developers have used different methods to inform users of changes for some time. Some put git commits into into a text file and package it with the app. Others may forgo any formal change notification. In one case you can over inform users (git commits) and then again no change tracking is just as harmful. You want a goldilocks type solution. Keep a Changelog.

The procedure and formatting around the Keep a Changelog template make it stand out. Most developers are already familiar with Markdown. It makes documents look nice with a minimal syntax. It's ideal for a Changelog.

It's also easy to integrate a Markdown page into your application. To display a markdown as in a .dotnet core web app, I used CommonMark. With a few lines of code I added a changelog to the project.

Here is the code.

@model Namespace.ChangelogViewModel

@{
    ViewBag.Title = "Changelog";
}

<div class="changelog container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            @Html.Raw(Model.Changelog)
        </div>
    </div>
</div>
public class HomeController : BaseController {
  
    private readonly IMarkDownToHtmlService _markdownService;

    public HomeController(
			IMarkDownToHtmlService markdownService,
			ILogger logger)
			: base(logger) {
			_markdownService = markdownService ?? throw new ArgumentNullException(nameof(markdownService));
    }

    [Authorize]
    public async Task<ActionResult> Changelog() {
        var vm = new ChangelogViewModel {
	Changelog = await _markdownService.ConvertMdFileToHtmlAsync(filePath: "~/Changelog.md").ConfigureAwait(false);
       };
	return View(vm);
    }
public class MarkDownToHtmlService : IMarkDownToHtmlService {

   private IFileService _fileService;

    public MarkDownToHtmlService(IFileService fileService) {
         _fileService = fileService;
    }

    /// <summary>
    /// Converts markdown to HTML
    /// </summary>
    /// <param name="filePath">Relative Server Path</param>
    /// <returns></returns>
    public async Task<String> ConvertMdFileToHtmlAsync(string filePath) {
    var serverpath = _fileService.ServerMapPath(filePath);
    using (var reader = new System.IO.StreamReader(serverpath)) {
        var fileContents = await reader.ReadToEndAsync();
	 return CommonMark.CommonMarkConverter.Convert(fileContents);
    }
  }
}

If you haven't added a changelog to your application take a few minutes and get started. Helpful document, even for developers :)

Over the years I have the privilege of helping several people get started coding. This is a short list of resources that I've found helpful in guiding others.

Courses & Lessons Pluralsight Udemy Codewars CodeKata

Online Reading Functional Programming – Wikipedia Object Oriented Programming – Wikipedia

Programming Help StackOverflow

Diving Deeper Software Craftsmanship Coding Horror Ploeh Blog – Software Design Teach Yourself Programming in Ten Years Separating Programming Sheep from Non-Programming Goats

In my last post I outlined creation of a 3D well plot with Helix Toolkit. In this post the original code will be refactored to include a two part tubular. The outer tube will represent the well bore, and the inner tube will represent the pipe in the well. Also, we will add a color gradient onto the tubing. Value sets can be mapped to the gradient to show something like temperature or pressures in a well. The refactored code is available in this Github Gist.

The Details

The data plotted in this 3D well viewer comes from a tubing forces torque and drag model. Force values are calculated at regular intervals of depth for tubing in the well. The outer well bore or casing is represented as a transparent glass tube. The pipe inside the well is the mapped gradient of force values (red to white).

Note: there is not a one to one mapping between well profile points and calculated forces. A well profile may be described by 20 or 30 data points describing the centerline of the wellbore. The torque and drag model may return several thousand data points for a length of pipe within the well. The data will need to be interpolated by depth to account for this.

Mapping Values as Texture Coordinates Helix toolkit uses the concept of texture mapping to apply a skin over the 3D objects. If you want to know more about texture mapping its explained in detail on [Wikipedia].

In this example, a linear gradient brush with values ranging from 0 to 1 is used. Values mapped to the brush will need normalized into the range of 0 to 1. Coordinates are given for where to apply the brush values on the geometry. Once a texture coordinates for each 3D point, we can databind them to our 3D plot in XAML

Get the Code: Github Gist

Here is a Github example project that contains all the code.

I've done a little work in the oil & gas industry. A common need in applications is to show a 3D plot of a well. My first rendition of a 3D well plot, I made in Excel. It was rather crude, and used a 3D to 2D orthographic transformation. Using this transform will let you plot a wireframe drawing onto a simple XY scatter plot type chart.

It's not beautiful or elegant but it works. But what if you want a more elegant plot? Something that looks a little better. If you're using WPF you have access to a decent 3D graphics rendering engine. Helix Toolkit gives you a little extra goodness. In this post I'll show you how I rendered a 3D well profile with Helix 3D toolkit.

Helix wraps the core WPF 3D functionality, to provide an extra level of sweetness and ease of use. One downfall of the project is the documentation. It is almost non-existent. But, the source code does have a great suite of sample applications. And as you should know, code samples are worth thousands of words :)

After looking through several of the 3D examples I was able to start piecing the chunks together. Helix support databinding making it simple to test your view-models. High level classes such as the Helix3DViewport provides panning, zooming, and rotation. This makes developing a sophisticated looking viewport very simple.

For my implementation of a well plot, I decided to have a small preview plot, and a larger window with 3D controls.

This larger window gives the user a more immersive 3D experience and a rich set of controls.

Get the Code: Github Gist

Issues: I did run into one issue. The preview plot uses one view instance. When a user clicks on a well, a new WellSurveyPlotViewModel is instantiated and the data context of the preview is updated. Opening the larger well viewer uses a window service to create a new window passing the WellSurveyPlotViewModel as its data context. The view refused to zoom to extents with the new camera information. After reading the source code I arrived at the idea of using an attached property to solve the issue. The following two lines, in an attached property hooked into a ReZoom boolean property in the preview view model solved the issue.

  viewport.Camera = viewport.DefaultCamera;
  viewport.ZoomExtents();

This toolkit is great! Using Helix, I was able to create the 3D well plot during a weekend of several short coding sessions. In an upcoming post I'll enhance the well viewer to provide a few more capabilities.

The WPF data grid has a property that controls the how headers get handled when copied. ClipboardCopyMode, can be set it to “IncludeHeader” or “ExcludeHeader” which is the default. There is the possibility the grid can exclude the header even in IncludeHeader mode. Let me explain.

The data grid header is customizable. It can use a header template object to place whatever you can imagine into the header. Imagine you want dancing clown gifs in the header of the grid. In WPF you can do that. Beware though, this is the condition that breaks IncludeHeader mode. Your dancing clowns won't make it to the clipboard.

For my example the header template includes a unit of measure displayed next to the column name. The user can change the unit of measure so this can't be a static value. The XAML markup looks like this.

 <UserControl.Resources>  
     <DataTemplate x:Key="FlowRate" DataType="DataGridColumnHeader">  
       <TextBlock Text="{Binding Source={x:Static units:UnitsContext.CurrentSymbols}, Path=FlowUnit, StringFormat=Flow-Rate ({0})}" />  
     </DataTemplate>  
     <DataTemplate x:Key="Pressure" DataType="DataGridColumnHeader">  
       <TextBlock Text="{Binding Source={x:Static units:UnitsContext.CurrentSymbols}, Path=PressureUnit, StringFormat=Pressure ({0})}" />  
     </DataTemplate>  
</UserControl.Resources>  

This creates a header in the table that looks like this. | Flow-Rated (BPD) | Pressure (psi) |

The issue is if we copy/paste from the grid into Excel we get this. | | |

The fix for this is actually relatively simple. The required text needs to get from the header template back up to the data grid. To do this we can use an attached property.

/// <summary>  
/// This attached property works with a header template that includes one TextBlock. Text content from the templates TextBlock is copied to the  
/// column header for the clipboard to grab.
/// </summary>  
   public static class TemplatedDataGridHeaderText {  
     private static readonly Type OwnerType = typeof(TemplatedDataGridHeaderText);  
     public static readonly DependencyProperty UseTextFromTemplateProperty = DependencyProperty.RegisterAttached("UseTextFromTemplate", typeof(bool), OwnerType, new PropertyMetadata(false, OnHeaderTextChanged));  
     public static bool GetUseTextFromTemplate(DependencyObject obj) {  
       return (bool)obj.GetValue(UseTextFromTemplateProperty);  
     }  
     public static void SetUseTextFromTemplate(DependencyObject obj, bool value) {  
       obj.SetValue(UseTextFromTemplateProperty, value);  
     }  
     private static void OnHeaderTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {  
       var textColumn = d as DataGridTextColumn;  
       if (textColumn == null) return;  
       if (textColumn.HeaderTemplate == null) return;  
       var headerTemplateTexblockText = textColumn.HeaderTemplate.LoadContent().GetValue(TextBlock.TextProperty).ToString();  
       textColumn.Header = headerTemplateTexblockText;  
     }  
   }  

In XAML this attached property can now be used to ensure the header text will make its way to the clipboard.

<DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False" IsReadOnly="True" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch">  
     <DataGrid.Columns>  
       <DataGridTextColumn Binding="{Binding FlowRate.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource FlowRate}"  
            attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>  
       <DataGridTextColumn Binding="{Binding Pressure.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource Pressure}"  
                 attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>  
     </DataGrid.Columns>  
</DataGrid>  

This is just one approach for solving this issue. Another might be to directly set the header text through an attached property.

Reference equality is the default comparator for objects in .Net, but it is seldom what I want when coding. More often I want to know if objects are the same based on the state they contain. Changing object equality comparison is as easy as overriding the Equals method. Yet, when you are using LINQ extension methods such as Distinct() or Contains() there are a few things to be aware of.

In Domain Driven Design (DDD) the value object pattern is frequently used.. Value objects in DDD don't need their own identity. They are identified by the uniqueness of all the information they contain. For example consider an Address object that has several fields (Street, City, State, Zip). No address is the same as another, unless all the field values are equal.

Imagine that we have a list of customer addresses and we want to return only the unique addresses.

 var addresses = new List<Address>() {
      Address = new Address("102 Birch", "Spring", "TX", 77777),
      Address = new Address("304 Elm", "Newport", "MA", 33234),
      Address =  new Address("102 Birch", "Spring", "TX", 77777)
};

var uniqueAddresses = addresses.Distinct();

Distinct calls the GenericEqualityComparer. This in turn uses the Equals & GetHashCode methods on the objects in the collection. GetHashCode is called to determine possible equality. Equals is called to determine absolute equality. Overriding GetHashCode is important in making the Distinct method work with the GenericEqualityComparer. If you fail to override GetHashCode, you will find the Distinct method does not work right. If LINQ collection extensions aren't working as expected this is likely the cause.

Guidelines for Object Equality & Hash Codes – If you have two objects considered equal then they should return the same hash. – Hash codes on mutable objects should be calculated off immutable fields. This keeps the hash the same through the object lifetime. – If you are using LINQ methods be sure that your objects aren't mutating and causing a hash code change. If for whatever reason you need to mutate objects in a collection, consider returning 1 as the hash. Caution: this will have a performance impact.

For a more in-depth look at all the things to consider, checkout this post by Eric Lippert.

A few more things to think about... LINQ collection extensions that do comparison allow passing in a EqualityComparer function. This is great as long as you control all the places in code where you need comparison. Beware of third party APIs that may have calls that would use the GenericEqualityComparer. Also, if you override equals, you may want to seal you class. This will prevent inherited classes from creating an incorrect Equals implementation. Lastly, override the equality (==) and inequality operators (!=) to avoid accidental comparison bugs.

EventAggregator is the Prism incarnation of the publish-subscribe pattern. Message classes are sent between components, keeping the components decoupled.

Writing unit tests against the Prism EventAggregator using Moq should be easy right? The IEventAggregator interface is provided by the Prism framework. We know interfaces make things testable. So yes this all should be possible. However, there is a good deal of confusion around this.

StackOverflow: Moq Event Aggregator is it possible? StackOverflow: Mocking Prism Event Aggregator using moq for unit testing StackOverflow: How to verify event subscribed using moq?

It's not as confusing or complex as confusion can make it :)

Imagine you have a subscription to an event, and the Action in the Subscribe() method is private. Using Moq the event needs to be published and the system under test needs to be examined for a state change.

[TestMethod]
public void EventAggregator_ReceivesUpdatedUnitsEvent_CallsOnUnitsUpdated(){  

  //Arrange  
  //Use the real event not a mock  
  _updateUnitsEvent = new UpdatedUnitsEvent(); 
  //Setup the mock EventAggregator to return the event  
  _mockEventAggregator.Setup(x => x.GetEvent<UpdatedUnitsEvent>())
                      .Returns(_updateUnitsEvent);    
  _mockUnits.Object.DensitySolid = DensitySolidSymbols.KgCm3; 

  //Act   
  //Trigger the event by publishing our payload   
  _updateUnitsEvent.Publish(_mockUnits.Object); 

  //Assert   
  _mockEventAggregator.Verify(x => x.GetEvent<UpdatedUnitsEvent>(), 
  Times.Once); 
  //Verify using Moq   
  var vm = _materialMasterVm.MaterialModels.Current as MaterialViewModel;
  //Check State 
  Assert.AreEqual(DensitySolidSymbols.KgCm3, vm.Density.UserUnitType); 
}  

Don't make the mistake of trying to use a mock for the message class.

Happy Coding!

This took place back in the days before Git became the standard for source control. Back then people used zip files saved into folders on the desktop. The wiser folks used centralized source control. The wild and crazy used some new thing called Git.

At work I had was tasked with setting up our source control. I went online and searched till I found a online provider offering SVN hosting. And that was the end of it. Years worth of work went into our cloud hosted SVN repos.

One morning I walked into work got my coffee sat down to pull the latest code from our SVN repository. My request returned with an error. At work the internet was coming over a 1mb line so it could be a little iffy. I tried again. Another error. Going down the rabbit hole I ended up going to the our SVN providers website.

I don't remember the exact wording but the message on the website read something like this...

“We are sorry to inform you that 'Acme SVN Hosting' is no longer in business. Our Amazon server was hacked because we used a weak password. The hacker demanded a ransom. We chose to not pay so we are out of business effective today. Sorry about your code, we hope you have a local copy”

Pretty basic mistake weak password. A tragic tale. They were out of business and we were no longer customers. Thankfully, we did have recent local copies and were able to piece things back together.

The easiest thing would have been to find another SVN provider and to continue using SVN. Instead I decided it would be a good time to switch source control. We moved over to TFS on Azure. Needless to say many pains were ahead of us. Looking back it is sad because Git was very mature by this time. This story makes the case for distributed source control. Why

Happy Coding!

Prism documentation is thorough. However, that makes it lack a certain conciseness that makes it easily digestible. One key thing that you will want to understand is how to get your views and view models connected. This post will quickly detail how to make it all work.

View Model Locator Configuration If your view model has a default constructor, it will be instantiated and matched to the view automatically. If your view models do anything interesting, they will likely not have default constructors. You will need to configure the view model locater to resolve constructor dependencies from your IOC container.

ViewModelLocationProvider.SetDefaultViewModelFactory(
    t => container.Resolve(t)
);

View to view model wiring is based on convention. They are match based on name, much like the familiar MVC conventions. Be careful though, if your views are suffixed with “view”, it will not work.

✅ Do this ViewModels.MyScenicViewModel – Views.MyScenic ❌ Don't do this ViewModels.MyScenicViewModel – Views.MyScenicView

The convention can be overridden with the following configuration point.

ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(
(viewType) => {
    ...
    return viewModelType;
});

View Specific Wire up Your view must implement the IView marker interface found in the Microsoft.Practices.Prism.Mvvm namespace.

public partial class Wizard : Window, IView {
    public Wizard() {
        InitializeComponent();
    }
}

And finally don't forget to set the auto wire up flag to true in your view.

<Window x:Class="MyProject.Views.Wizard"   
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:mvvm="clr-namespace:Microsoft.Practices.Prism.Mvvm;
 assembly=Microsoft.Practices.Prism.Mvvm.Desktop"
 Title="Wizard" Height="600" Width="800"
 mvvm:ViewModelLocator.AutoWireViewModel="True">

For a more in-depth read, check the Prism 5.0 Developers Guide.

I was listening to .Net Rocks! show 971 with Brian Noyes, and I was glad to hear that Microsoft dropped a new release of Prism – v5.0 for WPF. I have been using the Prism framework on a large application. It allows me to easily break the application into modules. For applications that need more than the simple MVVM support offered by frameworks like MVVM Light, it is a solid choice. All the code is on CodePlex. Here are the highlights of what is new in v5.0 – Broken into smaller more targeted assemblies – Updated NotificationObject to BindableBase – Includes a conventions-based View-Model Locator – Objects can be used to pass data around in Region Navigation

The Haters These are all great updates. Sadly, reading comments on CodePlex would make you think otherwise. Most comments are negative, directed at the complexity and learning curve of the Prism framework. Other comments seem like people blowing off steam about issues in WPF. Normally, I wouldn't pay much attention to comments of this nature. However, it struck me as odd that people have such backlash at technologies that are a clear improvement on previous generations.

For anyone discouraged by the complexity of Prism or WPF in general. Do not lose sight of what the patterns and frameworks surrounding WPF allow you to do. Ultimately, they are allowing you to write testable decoupled code. Be willing to embrace the pain that may be pushing you toward the pit of success.

Microsoft, thanks for the Prism Update! Happy Coding!

Enter your email to subscribe to updates.