Notes from Daily Encounters with Technology RSS 2.0
 
# Monday, August 18, 2014

Static code analysis is a very useful feature of ReSharper. The generated warnings can help you fix bugs which might otherwise remain unnoticed. Look at the following code:

Loop control variable is never changed inside loop

Do you see the issue? You would definitely have a more difficult time noticing it, if ReSharper didn’t warn you about it: Loop control variable is never changed inside loop. It might even remain unnoticed when surrounded by all the other code.

Unfortunately static analysis is not perfect and it might detect false positives - warning you about potential issues in code, which in reality aren’t issues at all. Let’s take a look at another example:

Access to disposed closure

ReSharper’s warning in this case: Access to disposed closure. The reason being: this code could fail if ExceptionAssert.Throws would store the lambda and execute it after scope was already disposed. Looking at its code, we can see, this is not the case:

public static T Throws<T>(Action action)
   where T : Exception
{
   try
   {
      action();
   }
   catch (T exception)
   {
      return exception;
   }
   Assert.Fail("No {0} was thrown.", typeof(T).FullName);
   return null;
}

The lambda is not being stored and is executed before the method completes, i.e. this ReSharper’s warning is a false positive.

There are a couple of ways to tell ReSharper about it, so that it doesn’t warn us any more. The simplest one is being offered as a quick fix: the check can be disabled with a special comment:

Disabling a warning with a comment

Although this works, it’s not a perfect solution since you need to add such a comment every time you call ExceptionAssert.Throws by passing it an IDisposable.

When we know that it’s always safe to pass an IDisposable to our method, we can tell that to ReSharper using its annotation attributes:

public static T Throws<T>([InstantHandle]Action action)
   where T : Exception
{
   try
   {
      action();
   }
   catch (T exception)
   {
      return exception;
   }
   Assert.Fail("No {0} was thrown.", typeof(T).FullName);
   return null;
}

This way we permanently got rid of the warning and the comment is not needed any more:

Disabling a warning with code annotations

To use the annotations, you either need to reference ReSharper’s JetBrains.Annotations.dll assembly or define the annotation attribute classes directly in your code. Unfortunately there’s no official NuGet package for either, but there’s plenty of unofficial options available. To my experience, it doesn’t really matter which one you choose, they all seem to achieve their goal just fine: you don’t need to reference an assembly from a proprietary location in your project or put it in source control.

The above of course only works when you have access to the source code. When you don’t, but you’d still like to improve ReSharper’s static code analysis, you can use external annotations. That’s how ReSharper’s authors have annotated the framework assemblies for you.

Monday, August 18, 2014 6:37:37 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | C# | Software | ReSharper | VisualStudio
# Thursday, August 14, 2014

After first hearing about C# Tips by Jason Roberts in a tweet less than a month ago, I decided to buy it and see whether the author can really contribute to writing better C# as he promises on the book’s web page. After reading it, I can agree.

As the title says, most of the book is dedicated to short tips and tricks on how to make the most of the language and improve your code. Currently there are 21 tips in the book and based on your previous experience you might already know about some of them. Still, I’m pretty sure, you’re going to learn at least something new. I must say, I wasn’t aware of all the nuances described in the book, although I’ve been using C# on almost daily bases since it was first released. And even for things you already know, it’s sometimes good to be reminded again.

The remaining two parts of the book; I didn’t like that much. Both design patterns and unit testing deserve more attention and you’re better of learning about them from dedicated books. Well, for those who will first hear about them here, it might be just enough to make them buy another book on the subject.

Nevertheless, the book is definitely worth getting. The author is letting the readers decide for themselves how much they think its worth and set their own price. Since this can be difficult based just on the info on the page, maybe this review can help you set the right price. I certainly don’t regret buying the book and I’m looking forward to it being completed. The author seems to be updating it regularly.

Thursday, August 14, 2014 6:44:31 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C# | Reviews
# Monday, August 11, 2014

One of the more attractive parts of Workflow Foundation is its workflow designer and the possibility of rehosting it in your own application with a minimum amount of code. Often simple rehosting of the designer is enough, but sometimes you will want to do some additional background processing of the workflow as the user is designing it. Here are a couple of ideas for such processing:

  • Ensure that each activity has a unique display name. In case of a duplicate display name append a sequential number to it (e.g. Sequence, Sequence 1, sequence 2, etc.).
  • Some custom activities require the designer to provide them with additional information, such as a list of valid values for a property in the current context. For this purpose they can expose a property, which the designer will set to a proxy data access class.

All such features require a traversal of all activities in the workflow. In this article I’m going to present a way for achieving that, implementing a simplified version of the first idea in the process: set the display name of each newly added activity to a random Guid value.

We first need to attach a handler to the designer’s ModelChanged event:

private void AddDesigner()
{
  //Create an instance of WorkflowDesigner class.
  this.wd = new WorkflowDesigner();

  //Place the designer canvas in the middle column of the grid.
  Grid.SetColumn(this.wd.View, 1);
  
  //Load a new Sequence as default.
  this.wd.Load(new Sequence());

  //Add the designer canvas to the grid.
  grid1.Children.Add(this.wd.View);

  //Attach the event handler
  var modelService = wd.Context.Services.GetService<ModelService>();
  modelService.ModelChanged += OnModelChanged;
}

The above code is based on the method from MSDN’s designer hosting tutorial.

In .NET 4.5 the only property of ModelChangedEventArgs that should be used, is ModelChangeInfo. In .NET 4 separate ItemsAdded, ItemsRemoved and PropertiesChanged properties are available instead, which are now marked as obsolete. The key to processing the changes is ModelChangeInfo.ModelChangeType. Based on it different types of changes can be handled in a different way.

In our scenario we only need to traverse newly added activities, therefore the only ModelChangeTypes of interest to us are CollectionItemAdded and PropertyChanged:

private void OnModelChanged(object sender, ModelChangedEventArgs e)
{
  switch (e.ModelChangeInfo.ModelChangeType)
  {
    case ModelChangeType.CollectionItemAdded:
    case ModelChangeType.PropertyChanged:
      RandomizeDisplayName(e.ModelChangeInfo.Value);
      break;
  }
}

In a naive first attempt we will search for the DisplayName property of the changed item and set it to the desired value:

private void RandomizeDisplayName(ModelItem item)
{
  if (item == null)
  {
    return;
  }

  var displayNameProperty = item.Properties
    .SingleOrDefault(property => property.Name == "DisplayName");

  if (displayNameProperty != null)
  {
    displayNameProperty.SetValue(Guid.NewGuid().ToString());
  }
}

This would work as long as the user would only add individual activities from the toolbox. Though, the designer also supports pasting of composite activities, e.g. a Sequence with multiple activities inside it. The above code would only set the display name of the root activity in such a case. To also process all its sub-activities, we need to recursively traverse the activity tree:

private void RandomizeDisplayName(ModelItem rootItem)
{
  if (rootItem == null)
  {
    return;
  }

  var displayNameProperty = rootItem.Properties
    .SingleOrDefault(property => property.Name == "DisplayName");

  if (displayNameProperty != null)
  {
    displayNameProperty.SetValue(Guid.NewGuid().ToString());
  }

  foreach (var modelProperty in rootItem.Properties)
  {
    if (typeof(Activity).IsAssignableFrom(modelProperty.PropertyType) ||
      typeof(FlowNode).IsAssignableFrom(modelProperty.PropertyType))
    {
      RandomizeDisplayName(modelProperty.Value);
    }
    else if (modelProperty.PropertyType.IsGenericType && 
      modelProperty.PropertyType.GetGenericTypeDefinition() == typeof(Collection<>) &&
      modelProperty.Collection != null)
    {
      foreach (var activityModel in modelProperty.Collection)
      {
        RandomizeDisplayName(activityModel);
      }
    }
  }
}

If you take a closer look at the above foreach loop, you can see that it only processes the Activity (e.g. branches of If activity) and FlowNode (a node inside a FlowChart) properties, and enumerates all collection properties (e.g. FlowChart Nodes or Sequence Activities).

This is already enough for our sample scenario, but since activity traversal will probably be a common operation in the hosted designer, we can refactor the above code for activity enumeration so that it can be used for any activity processing:

private void ProcessActivities(ModelItem rootItem, Action<ModelItem> action)
{
  if (rootItem == null)
  {
    return;
  }

  action(rootItem);

  foreach (var modelProperty in rootItem.Properties)
  {
    if (typeof(Activity).IsAssignableFrom(modelProperty.PropertyType) ||
      typeof(FlowNode).IsAssignableFrom(modelProperty.PropertyType))
    {
      ProcessActivities(modelProperty.Value, action);
    }
    else if (modelProperty.PropertyType.IsGenericType && 
      modelProperty.PropertyType.GetGenericTypeDefinition() == typeof(Collection<>) &&
      modelProperty.Collection != null)
    {
      foreach (var activityModel in modelProperty.Collection)
      {
        ProcessActivities(activityModel, action);
      }
    }
  }
}

The action to be performed on each activity can now be implemented in a separate method:

private void RandomizeDisplayName(ModelItem item)
{
  var displayNameProperty = item.Properties
    .SingleOrDefault(property => property.Name == "DisplayName");

  if (displayNameProperty != null)
  {
    displayNameProperty.SetValue(Guid.NewGuid().ToString());
  }
}

To do the processing, we can call the common traversal method, passing it the above implemented action:

private void OnModelChanged(object sender, ModelChangedEventArgs e)
{
  switch (e.ModelChangeInfo.ModelChangeType)
  {
    case ModelChangeType.CollectionItemAdded:
    case ModelChangeType.PropertyChanged:
      ProcessActivities(e.ModelChangeInfo.Value, RandomizeDisplayName);
      break;
  }
}

We now only have to implement a different action and pass it to ProcessActivities, to process them in a different way. No need to worry, how to actually enumerate all the sub-activities.

Monday, August 11, 2014 6:33:03 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | WF4
# Thursday, August 7, 2014

Portable class libraries have recently become so ubiquitous, that it’s easy to forget they don’t exist all that long. They weren’t even part of .NET 4, when it was originally released in 2010. As long as you’re using Visual Studio 2012 or later and targeting .NET 4.5, this is not really important. But once you start targeting .NET 4, you should better keep that in mind.

You might be referencing a portable class library in your project without even knowing it: it happened to me when updating CSLA to the latest version, which depends on Microsoft.Bcl.Async NuGet package implemented as a portable class library. This might affect your users if they’re not keeping their .NET 4 installation up-to-date. As documented on MSDN, portable class libraries require update KB2468871, .NET 4.0.3 or .NET 4.5 installed. Although the minimum required update has already been distributed via Windows Update, you shouldn’t take it for granted that all your customers already have it installed and fail to communicate the changed software requirements in time.

Of course portable class libraries affect the build process, as well. Again, if you have at least Visual Studio 2012 or Windows SDK for Windows 8 installed on your build server, you don’t need to worry. If you only have Visual Studio 2010 or .NET 4 SDK, the build will fail with a rather non-descriptive error:

d:\TeamCity\BuildAgent1\work\1955cf2ba61a55d8\Packages\Microsoft.Bcl.Async.1.0.168\
lib\net40\Microsoft.Threading.Tasks.Extensions.dll error CS1684: Warning as Error: 
Reference to type 'System.Net.WebResponse' claims it is defined in 'c:\Program Files (x86)\
Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Net.dll', but it could not be found
d:\TeamCity\BuildAgent1\work\1955cf2ba61a55d8\Packages\Microsoft.Bcl.Async.1.0.168\
lib\net40\Microsoft.Threading.Tasks.Extensions.dll error CS1684: Warning as Error: 
Reference to type 'System.Net.WebRequest' claims it is defined in 'c:\Program Files (x86)\
Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Net.dll', but it could not be found 

Installing the above mentioned .NET framework updates of course doesn’t have any effect, since they include only the runtime bits. Neither does it help to install .NET 4.0.3 Targeting Pack. To build .NET 4 projects, which reference portable class libraries, Portable Library Tools are required. Installing them from Visual Studio 2010 or from command line finally ensures a successful build.

I spent too much time figuring all this out. Hopefully this post will help others make it work sooner.

Thursday, August 7, 2014 6:35:19 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | .NET 4.5
# Monday, August 4, 2014

Creating a Windows service in .NET could hardly be any easier. There’s a template in Visual Studio which sets everything up and there’s even a detailed walkthrough published on MSDN which leads you through the whole process from creating a new project to actually installing the service.

Installing multiple instances of such a service on a single computer is not that easy. You could do it by using Sc.exe instead of InstallUtil.exe, or you could modify the installer in your Windows service project to support configurable names. I prefer the latter approach, but there’s not much documentation about it, which is probably the reason for many articles on the web describing over-complicated custom solutions instead of taking advantage of the APIs that are already available.

InstallUtil.exe has built-in support for passing the arguments to Windows service’s Installer class. The Installer base class parses them and puts them in a handy StringDictionary, which can be accessed through InstallContext. This means, you can read these values inside your Installer and use them to change the default service name:

private void SetServiceName()
{
  if (Context.Parameters.ContainsKey("ServiceName"))
  {
    serviceInstaller1.ServiceName = Context.Parameters["ServiceName"];
  }

  if (Context.Parameters.ContainsKey("DisplayName"))
  {
    serviceInstaller1.DisplayName = Context.Parameters["DisplayName"];
  }
}

Of course, it’s important, where this code is called from. If you try putting it in the class constructor, the installer will fail, because Context is not yet initialized. Fortunately the base class provides many virtual methods which you can override to get access to the Context after initialization. In our case we need to override OnBeforeInstall and OnBeforeUninstall:

protected override void OnBeforeInstall(IDictionary savedState)
{
  SetServiceName();
  base.OnBeforeInstall(savedState);
}

protected override void OnBeforeUninstall(IDictionary savedState)
{
  SetServiceName();
  base.OnBeforeUninstall(savedState);
}

The desired service name can now be passed as an argument to InstallUtil.exe:

installutil /ServiceName=A.Service /DisplayName="A Service" .\WindowsService1.exe

The same goes for uninstall:

installutil /u /ServiceName=A.Service .\WindowsService1.exe

To use the default name, the parameters can simply be omitted.

Monday, August 4, 2014 6:31:58 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET
My Book

NuGet 2 Essentials

About Me
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2014, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.