.NET

Fluent Assertions Release 1.2.2 has been released

It has been several weeks since we released a new version of the Fluent Assertions. Since then, a few small bugs were discovered and some features were requested. A few of these items have been fixed which resulted in a new release.

You can download version 1.2.2 from the CodePlex site.

Read more…

Technorati Tags:

Published: 29-06-2010 by Koen Willemse | 0 Comments | 0 Links to this post
 

ALM Practices Part 4: Common Code Layout

What is it?

A collection of rules stating what a block of code should look like. These may include rules on where line breaks are required, how to place parentheses, how much whitespace to put before and after those parentheses, how many spaces to use when indenting and where to insert empty lines.

Read more…


Published: 15-03-2010 by Dennis Doomen | 0 Comments | 0 Links to this post
 

Custom assertions make your tests more readable

In my last project quite some time was spent improving the readability of our unit tests. For this reason we have created a number of 'Should()' extension methods for several .NET types. Through this 'Should()' method you get access to a custom assertion class with assertions that are specific for that type. This way we are able to do the necessary assertions in a readable and more intention revealing way (OK, that is debatable, but that is how we see it).

The next table shows some examples of how you can do the assertions 'the old way' by using the Assert class, and how it will look when you use the Should() extensions.

Old way by using Assertion class With Should() extension method
Assert.AreEqual(1, products.First().Key); products.First().Key.Should().Equal(1);
Assert.AreEqual(10, products.Count()); products.Should().HaveCount(10);
Assert.IsTrue(person.Birthdate > DateTime.Today) person.Birthdate.Should().BeAfter(DateTime.Today);
CollectionAssert.Contains(products, newProduct); products.Should().Contain(newProduct);


You can also chain several assertions by using the 'And' constraint like this:

product.Code.Should()
    .HaveLength(10).And.StartWith("PC").And.EndWith("54"); 

There is also a 'ShouldThrow()' extension method that can be used to specify that a specific exception is expected when calling a method.

fileSystem.ShouldThrow(x => x.Open(@"C:\not_existing_file.txt")) 
    .Exception<FileNotFoundException>() 
    .WithMessage("Could not find file 'C:\not_existing_file.txt"); 

 

For all assertions you can supply a reason that states why you would expect this. In case of a failing test, the custom assertions classes will use this reason to compose a readable description of what was expected and why, and what was actually detected. For example:

product.Code.Should()
    .StartWith("PC",
    "because that is what the code for products from
     the 'Computers' category should start with");

 

If this assertion should fail, the following error message will be generated:

"Expected string starting with <PC> because that is what the code for products from the 'Computers' category should start with, but found <AB123>."

The Should extensions have been put in a separate project that you can easily use in your solution. It is very easy to extend the custom assertions, or to create a 'Should()' extension method with corresponding custom assertions for your own classes.

Download the Custom assertions library


Published: 27-06-2009 by Martin Opdam | 0 Comments | 0 Links to this post
 

Almost missed it but VSTS2010 beta1 is available for download!

Are you curious? I am, so what are you waiting for go to your msdn subscription and download VSTS2010 beta1; I am already installing ;-).


Published: 20-05-2009 by Hans ter Wal | 0 Comments | 0 Links to this post
 

Help prioritizing Enterprise Library 5.0

Patterns & Practices has just finished compiling a list of candidate features and improvements for the next installment of the Enterprise Library. Grigori Melnik, the Enterprise Library's product manager has opened an online survey and invites the .NET community to share their priorities and, if needed, add any additional requests. Make sure you add your vote over here.


Published: 01-04-2009 by Dennis Doomen | 0 Comments | 0 Links to this post
 

Best practice for accessing objects in ASP.NET cache

Fetching data from a webservice or a database can take some time. When it concerns static data that is used often in your application, it is wise to store the data in cache. That way you only have the performance hit of fetching the data once. ASP.NET has a HttpContext.Cache object that can be used to store your data. But what is the best way to read and write data in cache? And how do you handle the situation where multiple users of your web application access the same data in cache? I will try to answer these questions with an example.
Say you have a web application that uses a list of countries. The countries are stored in a database and do not change very often so you want to fetch and store the list in cache. You create a property 'Countries' that handles the fetching and caching of the countries. An obvious solution would be:

   1:  public List<string> Countries
   2:  {
   3:      get
   4:      {
   5:          // Try getting the countries from cache
   6:   
   7:          if (Cache["countries"] == null)
   8:          {
   9:              // Not in cache, so get the countries
  10:              // from the database and store them in cache
  11:              Cache["countries"] = GetCountriesFromDatabase();
  12:          }
  13:   
  14:          return (List<string>)Cache["countries"];
  15:      }
  16:  }

However, this is not a very good solution, because you should never assume objects in cache to be there. The cache can be expired at any time (for example because of a lack of resources). Even right after an object has been stored in cache, it can be removed. If, in the above example, the cache is cleared just before the return statement, the Countries property will incorrectly return null. To solve this, we should use a temporary variable. Like this:

   1:  public List<string> Countries
   2:  {
   3:      get
   4:      {
   5:          // Try getting the countries from cache
   6:          List<string> countries = (List<string>)Cache["countries"];
   7:          if (countries == null)
   8:          {
   9:              // Not in cache, so get the countries 
  10:              // from the database and store them in cache
  11:              countries = GetCountriesFromDatabase();
  12:              Cache["countries"] = countries;
  13:          }
  14:   
  15:          return countries;
  16:      }
  17:  }

This is better, because now it is no longer possible to return null when the cache is cleared. But this solution is not optimal either. What happens when multiple users are using the application at the same time and the Countries property is called from multiple threads simultaneously. When this happens before the cache has been filled it will result in multiple expensive calls to the database, just to get the same list of countries and store it in cache. This will degrade the overall performance. It would be enough to let just one thread fetch the countries and store them in cache. This can be accomplished by using locks:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          lock (CountriesCacheLock)
   8:          {
   9:              // Try getting the countries from cache
  10:              List<string> countries = (List<string>)Cache["countries"];
  11:              if (countries == null)
  12:              {
  13:                  // If not available from cache, apply a lock to fill the
  14:                  // cache in a thread-safe way. This avoids that multiple 
  15:                  // threads will simultaneously fetch the same list of
  16:                  // countries from the database
  17:                  countries = GetCountriesFromDatabase();
  18:                  Cache["countries"] = countries;
  19:              }
  20:   
  21:              return countries;
  22:          }
  23:      }
  24:  }

With the lock in place only one thread at a time can access the implementation of the Countries property, so there will be no more simultaneous calls to get the countries from the database. And still this is not an optimal solution, because now multiple threads must wait for each other before they can read the cache which is a loss of performance. Reading a value from cache is a thread-safe operation and could therefore be done by multiple threads at the same time. So the reading of the cache should be moved outside the lock:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          // Try getting the countries from cache
   8:          List<string> countries = (List<string>)Cache["countries"];
   9:          if (countries == null)
  10:          {
  11:              lock (CountriesCacheLock)
  12:              {
  13:                  // If not available from cache, apply a lock to fill the
  14:                  // cache in a thread-safe way. This avoids that multiple 
  15:                  // threads will simultaneously fetch the same list of
  16:                  // countries from the database
  17:                  countries = GetCountriesFromDatabase();
  18:                  Cache["countries"] = countries;
  19:              }
  20:          }
  21:   
  22:          return countries;
  23:      }
  24:  }

But now we are back to the performance issue of multiple threads accessing the Countries property when the cache has not been filled. In such situation, the first thread will apply the lock en start the time consuming operation of fetching the list of countries. Threads that in the meantime access the Countries property will have to wait for the lock to be released. But when that happens each thread that has been waiting for the lock will still go and fetch the list of countries again. For this to work more efficiently we will have to check again if the cache has been filled within the lock. Only if the cache is still empty we have to do the expensive database call. The final solution now looks like this:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          // Try getting the countries from cache
   8:          List<string> countries = (List<string>)Cache["countries"];
   9:          if (countries == null)
  10:          {
  11:              // If not available from cache, apply a lock to fill the
  12:              // cache in a thread-safe way. This avoids that multiple
  13:              // threads will simultaneously fetch the same list of
  14:              // countries from the database.
  15:              lock (CountriesCacheLock)
  16:              {
  17:                  // Try getting the countries from cache again, because the
  18:                  // cache might have been filled while waiting for the lock
  19:                  countries = (List<string>)Cache["countries"];
  20:                  if (countries == null)
  21:                  {
  22:                      // If still not in cache, get the countries 
  23:                      // from the database and store them in cache
  24:                      countries = GetCountriesFromDatabase();
  25:                      Cache["countries"] = countries;
  26:                  }
  27:              }
  28:          }
  29:   
  30:          return countries;
  31:      }
  32:  }

See also:
http://stackoverflow.com/questions/39112/what-is-the-best-way-to-lock-cache-in-aspnet


Published: 10-03-2009 by Martin Opdam | 0 Comments | 0 Links to this post
 

Connecting a WCF Dual Channel service to ASP.NET

My favority hobby project is an MP3 music jukebox. The first incarnation of this project was written for my previous company 3 years ago. It has the following features:

    • Runs as a service on a PC with at least Windows XP
    • Can play MP3 music files
    • Builds a database with tags of songs from a folder structure loaded with MP3s
    • Multiple users can register to request songs using a web client or a windows client (Windows XP or Vista)
    • When a user requests a song it will be placed in a requests list
    • The jukebox plays the songs from the request list, when idle the jukebox plays random songs
    • Users can pause, skip songs and the volume can be changed
    • Users can rate songs
    • The database tracks all requests and all skip operations for all users iindividually to be able to play an overall top N on a friday afternoon (for instance).

The Juke

In the last version the clients were communicating with the service by reading and writing in the database. Crude but effective. This time I put my spare time in turning the service into a WCF service. To allow the Windows clients to function very efficively I chose to use WCF dual channel contracts. This resulted in the following JukeBox interfaces:

   1: [ServiceContract(CallbackContract = typeof(IAvSolJukeCallBack), SessionMode = SessionMode.Required)]
   2: public interface IAvSolJukeService 
   3: {
   4:     [OperationContract(IsOneWay = true)] 
   5:     void ScanForNewSongs(string path); 
   6:  
   7:     [OperationContract(IsOneWay = true)] 
   8:     void FindSongs(string searchText); 
   9:  
  10:     [OperationContract(IsOneWay = true)] 
  11:     void AddRequest(int playerID, int userID, int songID); 
  12:  
  13:     [OperationContract(IsOneWay = true)] 
  14:     void AddRating(int userID, int songID, int value); 
  15:  
  16:     [OperationContract(IsOneWay = true)] 
  17:     void SkipPlayerSong(int playerID, int userID); 
  18:  
  19:     [OperationContract(IsOneWay = true)] 
  20:     void PausePlayer(int playerID, int userID); 
  21:  
  22:     [OperationContract(IsOneWay = true)] 
  23:     void VolumeUp(int playerID, int userID); 
  24:  
  25:     [OperationContract(IsOneWay = true)] 
  26:     void VolumeDown(int playerID, int userID); 
  27:  
  28:     [OperationContract(IsOneWay = true)] 
  29:     void Visit(int playerID, string guid, string name); 
  30:  
  31:     [OperationContract(IsOneWay = true)] 
  32:     void Join(int playerID, string guid, string name); 
  33:  
  34:     [OperationContract(IsOneWay = true)] 
  35:     void Leave(int playerID, int userID); 
  36:  
  37: } 
  38:  
  39: [ServiceContract(SessionMode = SessionMode.Required)]
  40: public interface IAvSolJukeCallBack
  41: {
  42:     [OperationContract(IsOneWay = true)]
  43:     void Identified(int userID, string playerName); 
  44:  
  45:     [OperationContract(IsOneWay = true)]
  46:     void NowPlaying(string title, string artist, string album); 
  47:  
  48:     [OperationContract(IsOneWay = true)]
  49:     void StatusChange(Status status); 
  50:  
  51:     [OperationContract(IsOneWay = true)]
  52:     void PlayListChange(Song[] list); 
  53:  
  54:     [OperationContract(IsOneWay = true)]
  55:     void FindSongResults(Song[] list);
  56: } 
  57:  

The basics come from the well known Chat Service sample. Opening a TCP channel with MEX support from a System.ServiceProcess.ServiceBase class based windows service is not very difficult.

   1: /// <summary>
   2: /// Windows service OnStart override 
   3:  
   4: /// </summary> 
   5:  
   6: protected override void OnStart(string[] args)
   7: { 
   8:  
   9:     if (_serviceHost != null)
  10:     {
  11:         _serviceHost.Close();
  12:     }
  13:     // Create a ServiceHost for the AvSolJukeService type and 
  14:     // provide the base address.
  15:     _serviceHost = new ServiceHost(typeof(AvSolJukeService));
  16:     // Open the ServiceHostBase to create listeners and start 
  17:     // listening for messages.
  18:     _serviceHost.Open(); 
  19:  
  20:     // Initialize the player.... 
  21:  
  22: ... 
  23:  
  24: } 
  25:  
  26: /// <summary>
  27: /// Windows service OnStop override 
  28:  
  29: /// </summary> 
  30:  
  31: protected override void OnStop()
  32: {
  33:     // Stop the player... 
  34:  
  35:       ... 
  36:  
  37:     if (_serviceHost != null)
  38:     {
  39:         _serviceHost.Close();
  40:         _serviceHost = null;
  41:     }
  42: } 
  43:  

This is how the AvSolJukeCallBack service implementation retrieves the CallBack channel:

   1: /// <summary>
   2: /// This property gives access to the callback channel. The callback channel notifies clients 
   3: /// about the current status and status changes of the player service.
   4: /// </summary>
   5: public IAvSolJukeCallBack ClientCallBack
   6: {
   7:     get
   8:     {
   9:         if (_clientCallback == null)
  10:             _clientCallback = OperationContext.Current.GetCallbackChannel<IAvSolJukeCallBack>();
  11:         return _clientCallback;
  12:     }
  13: } 

And this in the app.config:

   1: <system.serviceModel>
   2:   <services>
   3:     <service name="AvSol.Juke.Service.AvSolJukeService" behaviorConfiguration="MEX">
   4:       <host>
   5:         <baseAddresses>
   6:           <add baseAddress = "net.tcp://localhost:1040/AvSolJukeService"/>
   7:         </baseAddresses>
   8:       </host>          <!-- Service Endpoints -->
   9:       <endpoint address="MEX" binding="mexTcpBinding" contract="IMetadataExchange"/>
  10:       <endpoint address="net.tcp://localhost:1040/AvSolJukeService" binding="netTcpBinding" contract="AvSol.Juke.Service.IAvSolJukeService"/>
  11:     </service>
  12:   </services>
  13:   <behaviors>
  14:     <serviceBehaviors>
  15:       <behavior name="MEX">
  16:         <serviceMetadata/>
  17:       </behavior>
  18:     </serviceBehaviors>
  19:   </behaviors>
  20: </system.serviceModel> 

Writing the windows client is a breeze. First the windows client should call Join. When successful it will be followed by an initial callback Identified and subsequent callbacks StatusChange, NowPlaying, PlayListChange every time something happens in the jukebox. Calling FindSongs will eventually result in the FindSongResults callback. When the windows client closes it should call Leave. This will stop the callbacks and allows the client to stop the connection gracefully.

However, when working on this I forgot about the Web client. How do you get this callback mechanism to work in the web request/response world? Can you use AJAX to callback into your web page? Fortunately I found an article that showed how to use WaitHandle to turn the asynchronous callbacks into single synchronous calls. When callbacks trigger subsequent AutoResetEvent objects, an initiating call can wait for one or more callbacks to signify completion.

The jukebox WCF service now needed a little rewrite. For the purpose of the web client I introduced the Visit call. The Visit call replaces the Join operation and will always in sequence send the callbacks Identified, StatusChange, NowPlaying, PlayListChange. Visit needs no to call Leave to stop broadcasts, because it simply doesn't start the broadcasting process at all. FindSongs and FindSongResults also do not need a broadcast session. A wrapper around the client can call Visit or FindSongs and wait for the callbacks. The wrapper should also correctly handle the threading of the WCF calls. Here is the implementation of the Visit in the web client wrapper class, the AvSolJukeServiceClient has been generated by the Add Services option of Visual Studio 2008:

   1: /// <summary>
   2: /// This request Joins the service and Leaves it again in a synchronous operation to retrieve only the current status.
   3: /// </summary>
   4: /// <param name="userGuid"></param>
   5: /// <param name="name"></param>
   6: /// <returns></returns>
   7: public int Visit(string userGuid, string name)
   8: {
   9:     WaitHandle[] waitHandles = { _waitIdentifiedHandle, _waitNowPlayingHandle, _waitStatusChangeHandle, _waitPlayListChangedHandle }; 
  10:  
  11:     using (AvSolJukeServiceClient client = new AvSolJukeServiceClient(new InstanceContext(this)))
  12:     {
  13:         client.Open();
  14:         client.Visit(1, userGuid, name);
  15:         WaitHandle.WaitAll(waitHandles, MAXWAITIDENTIFIED, false);
  16:         client.Close();
  17:     }
  18:     return _userID;
  19: } 

And snippet to show how to handle one of the events:

   1: /// <summary>
   2: /// Implementation of the Identified callback method
   3: /// </summary>
   4: /// <param name="userID"></param>
   5: /// <param name="playerName"></param>
   6: void IAvSolJukeServiceCallback.Identified(int userID, string playerName)
   7: {
   8:     _userID = userID;
   9:     PlayerName = playerName;
  10:     _waitIdentifiedHandle.Set();
  11: } 
  12:  

Now the ASP.NET page can call the wrapped Visit in the Page_Load. It then has all the information it needs to show the status and current requests. A search button on the page calls a wrapped FindSongs and waits for the callback to show the results. The web client uses the WCF service in a real stateless way. To my knowledge this results in the best achievable way to use the WCF dual channel service.

Now the jukebox is a dynamic service, people request songs, press pause and play and skip songs. The web page now only shows the results after a reload of the page. How to get the very dynamic service into the not so dynamic request/response jacket? I chose AJAX and polling.

I moved the controls showing the dynamic stuff like the status and the current requests in an UpdatePanel and hooked it up to an AJAX Timer. Next step was to put the FindSongs in an AJAX Web script service proxy and call it from script using the ScriptManager on the aspx page.

I hope this gives you some grip on getting WCF working in your ASP.NET web apps. If you have any other input on this ever ongoing hobby project, you're welcome.


Published: 04-11-2008 by Wim The | 0 Comments | 0 Links to this post
 

Removing namespaces from XHTML

Last week we needed to get some html fragments from a XHTML document. A straightforward process one might say, although we ran into some namespace problems along the way.

Unlike HTML, XHTML is in essence a XML document and you can therefore use the XmlDocument class to load an in memory representation of the document.

Our document:

   1:  <?xml version="1.0" encoding="utf-8"?><!DOCTYPE html
   2:    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   3:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="nl">
   4:     <head>
   5:        <title>title something</title>
   6:     </head>
   7:     <body>
   8:        <div id="broodtekst">
   9:           <h1>get this part</h1>
  10:        </div>  
  11:     </body>
  12:  </html>

Our objective is to retrieve the html in between the <div id="Broodtekst"><h1>get this part</h1></div>.

Retrieving the html:

   1:  string result = string.Empty;
   2:  XmlDocument doc = new XmlDocument();
   3:   
   4:  doc.Load(bestand);
   5:  XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
   6:  man.AddNamespace("d", "http://www.w3.org/1999/xhtml");
   7:              
   8:  XmlNode node =  doc.SelectSingleNode("//d:div[@id='broodtekst']",man);
   9:  result = node.InnerXml;

 

Our result unfortunately did not yield the expected string "<h1>get this part</h1>", in stead it yielded "<h1 xmlns="http://www.w3.org/1999/xhtml">get this part</h1>". It turn out the XmlDocument keeps track out of which namespace the html is queried and puts the namespace in all the tags related to the namespace. A good feature, but not what we wanted. After a lot of searching and asking around our colleague Keren came up with the answer (thx Keren). Remove all the namespaces from the XmlDocument before proceding with a XPath query.

Removing all namespaces and retrieve html:

   1:   string result = null;
   2:  System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
   3:  using (MemoryStream ms = new MemoryStream(bestand))
   4:  {
   5:       using (XmlTextReader tr = new XmlTextReader(ms))
   6:       {
   7:             tr.Namespaces = false;
   8:             tr.ProhibitDtd = false;
   9:             doc.Load(tr);
  10:        }
  11:   }
  12:  //Extract content div
  13:  XmlNode node2 = doc.SelectSingleNode("//div[@id='broodtekst']");
  14:  if (node != null)
  15:  {
  16:       result = node2.InnerXml;
  17:  }

Instead of loading the stream directly into the XmlDocument class you put it in a XmlTextReader which has a couple of sweet properties to remove namespaces (line 7) and prohibit the XmlDocument to retrieve optional DTD files (line 8, thx William).

Hopefully this might help some people in the .Net community struggeling with XML/XHTML and namespaces.


Published: 22-09-2008 by Hans ter Wal | 0 Comments | 0 Links to this post
 

Single Sign On

I was configuring a website for a customer with single sign on using forms authentication, the previous configurations used resulted in unreliable sign on.
 
So I found the following excellent blogpost describing the steps needed to use single sign on using forms authentication. http://weblogs.asp.net/hernandl/archive/2004/06/09/ssoformsauth.aspx
 
It seemed that the trick was in the machinekey element.
 
So i found another site to create the appropriate key for me:
 
Like they say in Dutch "Doe er je voordeel mee!"
 
See also:
 
Hope this helps!
 
 
 

Published: 13-06-2007 by Frans Bruijnen | 0 Comments | 0 Links to this post
 

WWF as a controller for the UI

Over the last three months I have been experimenting extensively to get to grips with the Windows Workflow Foundation (WWF). The main purpose for me is to see if workflow can be a part of controlling the UI dialog with the user interactively. If you have been using WWF and had the same interest as me you would probably have found that neither the regular sequential workflow nor the state machine workflow forms really fits the interactive UI model. Especially if you want to have a 'Go Back' in the UI, things get really hairy.

You would expect the Patterns and Practices people from Microsoft to have a special interest in WWF, because there really is a good story in putting the Model-View-Controller pattern in user interaction and have the Model and Controller part of this pattern work graphically with WWF. Now someone else stood up at Microsoft and introduced a new product: ASP.NET PageFlow. It shows up as new WWF templates: UI Workflow. It combines elements of the sequential workflow and the state machine workflow. Of course it supports 'Go Back'. You can find an introduction of the first prototype code here.

It will be interesting to see if this catches on and results in a downloadable CTP code soon, because it really fills a gap in WWF. Kashif Alam promises that it will show up later this year…


Published: 16-04-2007 by Wim The | 0 Comments | 0 Links to this post
 
 Next >>