Some time ago I read about (might be on Dot­NetRocks) a lit­tle gem com­ing out of Microsoft’s research lab called Pex, which is a frame­work for doing auto­mated White Box Test­ing in .Net. It’s still in its early days (despite hav­ing been around for more than 2 years now) but packs a bag of poten­tial judg­ing by what I’ve seen of the demo mate­ri­als and been able to use myself!

In short, Pex is able to ana­lyze your meth­ods and work out the bound­ary con­di­tions, etc. and derive a series of tests that can be used to test your method with as high a cov­er­age as pos­si­ble. The down­load pack­age also includes a light­weight frame­work for test stubs and detours (which basi­cally allows you to replace any .Net method with your own del­e­gate) called Stubs and Moles. It also comes with the abil­ity to auto­mat­i­cally gen­er­ate test project for you in MSTest and NUnit though I haven’t tested out the NUnit gen­er­a­tion as it didn’t sup­port NUnit gen­er­a­tion the last time I played around it.

I won’t go into detail on how to use it as there are a ton of doc­u­men­ta­tion and demo mate­r­ial on its site and I have barely scratched the sur­face myself, but do check it out if you haven’t done so already!

Share

I came across this blog post the other day which intro­duced to me a cool addi­tion to the Dat­a­Con­tract seri­al­izer — the abil­ity to gen­er­ate XML by ref­er­ence rather than by value:

http://www.zamd.net/2008/05/20/DataContractSerializerAndIsReferenceProperty.aspx

Not much for me to add to it really, just read the blog to see how it works.

Share

Using entity classes in your appli­ca­tion and WCF is com­plain­ing about the cir­cu­lar ref­er­ences between your classes? Well, I had the exact same prob­lem not long ago, and I found this post on James Kovac’s blog about cir­cu­lar ref­er­ences and how to get around them:

http://www.jameskovacs.com/blog/GoingAroundInCirclesWithWCF.aspx

The key things to note from this post is that:

  1. WCF can han­dle cir­cu­lar ref­er­ences, but is not switched on by default
  2. There is a boolean flag in the con­struc­tor for the Dat­a­Con­tract­Se­ri­al­izer class which enables object ref­er­ences to be preserved
  3. We can tell WCF to switch this on by deriv­ing from the Dat­a­Con­tract­Se­ri­al­ize­r­Op­er­a­tionBe­hav­iour class (as shown in the blog post above)

By this point you’re prob­a­bly won­der­ing why cir­cu­lar ref­er­ence han­dling is not enabled by default, accord­ing to James Kovac, it’s because WCF by default tries to respect inter­op­er­abil­ity safety:

Now why can’t WCF han­dle cir­cu­lar ref­er­ences out-of-the-box. The rea­son is that there is no industry-accepted, inter­op­er­a­ble way of express­ing any­thing but parent-child rela­tion­ships in XML. You can use the ID/IDREF fea­ture of XML or the key/keyref fea­ture of XML Schema, but a lot of seri­al­iz­ers don’t respect these attrib­utes or han­dle them prop­erly. So if you want to seri­al­ize cir­cu­lar ref­er­ences, you need to stray out of the realm of safe interoperability.

So here are the classes you need to cre­ate to extend Dat­a­Con­tract­Se­ri­al­ize­r­Op­er­a­tionBe­hav­iour in order to pre­serve object reference:

public class PreserveReferencesOperationBehavior : DataContractSerializerOperationBehavior
{
     public PreserveReferencesOperationBehavior(OperationDescription operation) : base(operation)
     {
     }

     public PreserveReferencesOperationBehavior(
          OperationDescription operation, DataContractFormatAttribute dataContractFormatAttribute)
          : base(operation, dataContractFormatAttribute)
     {
     }

     public override XmlObjectSerializer CreateSerializer(
          Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
     {
          return new DataContractSerializer(type, name, ns, knownTypes,
                                            0x7FFF /*maxItemsInObjectGraph*/,
                                            false/*ignoreExtensionDataObject*/,
                                            true/*preserveObjectReferences*/,
                                            null/*dataContractSurrogate*/);
     }
}

And the attribute to use on your oper­a­tion contract:

public class PreserveReferencesAttribute : Attribute, IOperationBehavior
{
     public void AddBindingParameters(OperationDescription description,
                                      BindingParameterCollection parameters)
     {
     }

     public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
     {
          IOperationBehavior innerBehavior = new PreserveReferencesOperationBehavior(description);
          innerBehavior.ApplyClientBehavior(description, proxy);
     }

     public void ApplyDispatchBehavior(OperationDescription description,
                                       DispatchOperation dispatch)
     {
          IOperationBehavior innerBehavior = new PreserveReferencesOperationBehavior(description);
          innerBehavior.ApplyDispatchBehavior(description, dispatch);
     }

     public void Validate(OperationDescription description)
     {
     }
}

which you apply like this:

[OperationContract]
[PreserveReferences]
MyClass RetrieveMyClass();
Share

The Dis­pose pat­tern is some­thing we’ve all seen before, and it’s so tried and tested most of us (espe­cially myself!) have been more than happy to apply with­out question.

Whilst read­ing var­i­ous blogs/articles I came across some dif­fer­ing opin­ion about this well known pat­tern and started to ques­tion what I had taken for granted myself.

After some more research and a ques­tion on the gold­mine of knowl­edge that is the Stack­Over­flow I have short­listed a few points you should con­sider when imple­ment­ing the stan­dard C# dis­pose pattern:

  1. if your object doesn’t hold any IDis­pos­able objects or unman­aged resources (DB con­nec­tion, for exam­ple) then you don’t need to imple­ment the IDis­pos­able or final­izer at all
  2. if your object doesn’t hold any unman­aged resources then don’t imple­ment a final­izer, the Garbage Col­lec­tor won’t attempt to final­ize your object (which has a per­for­mance hit) unless you have imple­mented a finalizer.
  3. don’t for­get to call Dis­pose() on each of the IDis­pos­able objects in the Dispose(bool) method.
  4. if your object holds unman­aged resources, clean them up in the final­izer with­out re-writing any of the cleanup code in the Dispose(bool) method already.

So for a sim­ple class with no unman­aged resources and a col­lec­tion of IDis­pos­able objects, your class might look some­thing like this:

public sealed class MyClass : IDisposable
{
     IList<MyObject> objects;  // MyClass holds a list of objects
     private bool _disposed;   // boolean flag to stop us calling Dispose(twice)

     public void Dispose()
     {
          Dispose(true);
          GC.SuppressFinalize(this);
     }

     private void Dispose(bool disposing)
     {
          if (!_disposed)
          {
               // call Dispose on each item in the list
               if (disposing)
               {
                    foreach (var o in objects)
                    {
                         // check if MyObject implements IDisposable
                         var d = o as IDisposable();
                         if (d != null) d.Dispose();
                    }
               }
          _disposed = true;
          }
     }
}

This is fairly sim­i­lar to the stan­dard C# Dis­pose pat­tern, the main dif­fer­ence being the lack of a final­izer because remem­ber, imple­ment­ing a final­izer will impact the per­for­mance of your type so don’t imple­ment it unless you need it.

Share

Over the last cou­ple of years, there have been many discussions/debates on DataSet vs Col­lec­tions, and there was a very good arti­cle in MSDN mag­a­zine on just that:

http://msdn.microsoft.com/en-gb/magazine/cc163751.aspx#S7

To add to the Dark Sides of DataSet, there is a lit­tle known feature/bug/annoyance in the DataTable.Select() method — every time you call the Select() method it cre­ates a new index implic­itly with­out you hav­ing any con­trol over it, and the index is not cleared until you call DataTable.AcceptChanges().

If your appli­ca­tion has to deal with a large amount of data and have to use the Select() method repeat­edly with­out call­ing AcceptChanges() then you might have a prob­lem! Why? Con­sider these two factors:

1. the big­ger the DataT­able, the big­ger the index, and if the index object is big­ger than 85kb it gets allo­cated to the Large Object Heap which are not cleared auto­mat­i­cally by the Garbage Collector/takes much longer to clear than small objects

2. in a 32-bit win­dows sys­tem, there’s a 2GB Vir­tual Address Space limit for each process, and in prac­tice, you will usu­ally get an Out­OfMem­o­ryEx­cep­tion when your process has used around 1.2GB — 1.5GB of RAM

com­bine them and it’s not hard to imag­ine a sce­nario where your process might actu­ally run out of mem­ory and crash out before it com­pletes its task! (Believe me, it was a hard learned les­son from my per­sonal experience!)

Solu­tions:

1. unless you actu­ally need some of the fea­tures DataSet offers such as the abil­ity to keep mul­ti­ple ver­sions of the same row (Orig­i­nal, Cur­rent, etc.) you might be bet­ter off with using POCO (plain old CLR object) instead which are sim­ple, light­weight and you can use LINQ to Objects with i4o to get some impres­sive per­for­mance improve­ments. After I imple­mented this change, my appli­ca­tion went from crash­ing out with Out­OfMem­o­ryEx­cep­tion to max­ing out at 70MB through­out its life­time and fin­ished in about 15% of the time it’d have taken using DataSet.

2. if get­ting rid of DataSet alto­gether takes a lit­tle too much time and effort than you can afford, then there’s a quick workaround by using a DataView and dynam­i­cally change the Fil­ter string every time you intend to call the Select() method.

If you wish to learn more about Garbage Col­lec­tion in gen­eral, you should read Maoni’s WebLog which cov­ers all things CLR Garbage Col­lec­tor! He also wrote a nice arti­cle focused on Large Object Heap back in June 2008 which is well worth a read:

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

Share