Wednesday, March 24, 2010

Too-Busy Constructors

In dealing with a more complicated OO design, it can be a mistake to put too much initialization logic into constructors. This is especially important for an OO design that uses inheritance significantly. In this post I offer three reasons against doing too much in a constructor. lazy loading, exception handling, and control over execution order.


First, lets look at control over execution order. It can become complex to reason about the order in which code gets executed. It is necessary to distinguish between the execution of data field initializers and the code in the constructor. I blog here about the exact sequences that occur in VB.NET and C#. The languages have a significantly different ordering! Moving initialization logic into a separate initialization routine can allow you to control this order more precisely, without having to fit logic into object initialization as implemented by your .NET language.


Second, the lazy loading pattern is an extremely useful technique to be aware of. Martin Fowler articulates the lazy load pattern well within his Patterns of Enterprise Application architecture. The basic idea behind lazy loading is that it can be significantly more efficient to delay gathering data until it is actually needed. It is possible that the data may never actually be needed. At the same time, a calling class need never know about the lazy implementation. It can call the object that employs lazy loading and simply assume that the data will be available when it is needed. For some things that are naively done in the constructor, using the lazy load technique is the best way to go.


Third, handling exceptions generated from within a constructor can prove difficult. If the exception should prove critical and can’t be easily handled then the code execution flow can be messy. You have to allow for disposal of all relevant objects and resources obtained so far. You also need to consider what the results of the exception unwinding the call stack will be.


In my own experiences with profiling .NET applications, object creational concerns have proven to a significant cause of inefficiency. In one case, I found that there were an excessive number of Oracle connection objects being created. These connections weren’t actually being opened (thankfully!) but they were instantiated nonetheless. Having constructors do less and instantiating fewer aggregated objects can result in code that is more manageable and more efficient.

Field initializer differences between C# and VB.NET

There are many subtle problems which exist when porting code between C# and VB.NET. One involves inheritance and the order of initialization for fields in a class. I learned about this from reading .NET Gotcha’s by Venkat Subramaniam (Gotcha #27). In C#, fields initializers are executed in order from child to parent and then constructors are called from parent to child. In VB.NET, field initializers are executed immediately before the constructor of the relevant. As with C#, constructors are called from parent to child. Here is a simple example that illustrates how different behavior can result.


The VB.NET code looks like this:
 Public Class Sample1  
Public Sub New()
Debug.WriteLine("Sample1 constructor")
End Sub
End Class
Public Class Sample2
Public Sub New()
Debug.WriteLine("Sample2 constructor")
End Sub
End Class
Public Class Parent
Public oSam1 As New Sample1
Public Sub New()
Debug.WriteLine("Parent constructor")
End Sub
End Class
Public Class Child
Inherits Parent
Public oSam2 As New Sample2
Public Sub New()
Debug.WriteLine("Child constructor")
End Sub
End Class

The C# code looks like this:
   class Sample1  
{
public Sample1()
{
Debug.WriteLine("Sample 1 constructor");
}
}
class Sample2
{
public Sample2()
{
Debug.WriteLine("Sample 2 constructor");
}
}
class Parent
{
public Sample1 Sam1 = new Sample1();
public Parent()
{
Debug.WriteLine("Parent constructor");
}
}
class Child:Parent
{
public Sample2 sam2 = new Sample2();
public Child()
{
Debug.WriteLine("Child constructor");
}
}

Despite the seemingly identical code, the order of execution varies significantly.
In VB.Net the output is:

  1. Sample1 constructor

  2. Parent constructor

  3. Sample2 constructor

  4. Child constructor


But in C# the output is:

  1. Sample 2 constructor

  2. Sample 1 constructor

  3. Parent constructor

  4. Child constructor


There are a couple of approaches that allow this concern to be resolved easily. One simple solution to this problem is to separate construction of objects from effectively initializing their state. For example, having the classes Sample1 and Sample2 put their logic in an Init method would allow a more consistent and predictable behavior. Another approach is to assign the reference (i.e. “new up”) to data fields within the constructor. I expound on the more general flaw of doing too much in constructors here.

Monday, March 22, 2010

Typesafe enumerations in .NET

One of the weaker aspects of C# and VB.NET is the lack of support for strongly-typed enumerations. The enum type in VB.NET uses whole numbers as a backing store with Integer being the default backing store type. Since enums are a value type based on whole numbers, they can have mathematical operations applied to them. You can, for example, add or subtract to their value. More importantly, you can assign a value to an enum that is not actually part of the enum. As programmers we make an association between the enum and backing store and face the temptation of dealing with the underlying store and explicitly assigning a value. This applies even to code that could be identified as buggy at compile-time. It is possible to identify whether an enum has a valid value by using the System.Enum.IsDefined function.


Here is an example of a convention enum that illustrates the weaknesses of the Enum type.


 Enum ConnectionStatus  
Closed
Open
Retrying
End Enum
Sub BuiltInEnumTest()
Dim connectionType = ConnectionStatus.Open
Console.WriteLine()
connectionType += 5
If [Enum].IsDefined(GetType(ConnectionStatus), connectionType) = False Then
Console.WriteLine("Out of bounds value")
End If
End Sub



One of the many takeaways I gained from a course with JP Boodhoo (his famous Nothing But Net Course) was how to create what can be treated like a typesafe enum. The idea is to have a class that equates to the enum type with static variables representing instances of objects that are the value of the enum. In my version, I add a private constructor so that an instance of the enum type can’t be created outside of the class. By removing the integer-based backing store, programmers are forced to treat the enum type as a black box. This ensures type-safety. Here is how this looks converted to a type-safe enum.


 Enum ConnectionStatus  
Closed
Open
Retrying
End Enum
Sub BuiltInEnumTest()
Dim connectionType = ConnectionStatus.Open
Console.WriteLine()
connectionType += 5
If [Enum].IsDefined(GetType(ConnectionStatus), connectionType) = False Then
Console.WriteLine("Out of bounds value")
End If
End Sub



There is one drawback worth mentioning. As a consequence of removing the integer-based backing store it is no longer possible to use the values in a Select statement in VB.NET 10. It is under consideration, however, for future versions of VB.NET to allow a select statement that allows type to be the selection criterion.

Thursday, March 18, 2010

Steve Bohlen on Practical DDD in .NET and Value Equality

I recently had the chance to see an excellent presentation by Steve Bohlen on Practical Domain Driven Design. It was given to the Philly ALT.NET user group. He has slides and example code available here. ). For numerous discussion points, he emphasized the range of options available. It was refreshing to hear this approach which wasn’t dogmatic in how to approach DDD.


He talked about his Proteus open source library which has some very useful code in it. I want to illustrate in this post one of the classes he uses for DDD category of classes know as value objects. Value objects don’t have a unique identifier for equality checks. Instead, value objects are equal when all fields match. Steve uses a ValueObject base class that allows any type to have its fields compared using reflection. This allows the creator of a value object to have the functionality of equality comparison without writing out all of the tedious plumbing code to compare two objects field by field and without the code clutter within the class. There is more to his class than this but this is a very significant method.


 public virtual bool Equals(TObject other)  
{
if (other == null)
{
return false;
}
FieldInfo[] fields = base.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo info in fields)
{
object obj2 = info.GetValue(other);
object obj3 = info.GetValue(this);
if (obj2 == null)
{
if (obj3 != null)
{
return false;
}
}
else if (typeof(DateTime).IsAssignableFrom(info.FieldType) || typeof(DateTime?).IsAssignableFrom(info.FieldType))
{
DateTime time = (DateTime) obj2;
string str = time.ToLongDateString();
string str2 = ((DateTime) obj3).ToLongDateString();
if (!str.Equals(str2))
{
return false;
}
}
else if (!obj2.Equals(obj3))
{
return false;
}
}
return true;
}

Tuesday, March 16, 2010

Want to become a better VB.NET programmer? Read C# In Depth!

I have been focusing lately on improving my VB.NET expertise. After reviewing the available books I decide to re-read C# in Depth by Jon Skeet (first edition) and really focus on how that translates to VB.NET. C# in Depth is definitely more theoretical than most other books. It is probably one of the few books that help to prepare for reading the actual C# language specification. I strongly recommend porting his example code to VB.NET and playing with these examples. Don’t just read the book.


I’d suggest start by working with a snippet editor. I spent a little time porting Jon’s snippet compiler/runner Snippy to be a VB.NET and will blog about that later in a bit. Alternatively, LinqPad is an excellent Snippet compiler and isn’t just for Linq.


Jon also spent a day presenting a deep dive into C# in Copenhagen and made the material available here. A good chunk of this actually goes deeper in depth than his book. It also just how well he did on focusing his book when you see how tangential he is in these talks. For the most part I would suggest, reading the book first. However, when you reach the promised land of Linq in the book, I suggest you view the first part of Session 6 which illustrates the characteristics of Linq using people as query operators. This beautifully illustrates important concepts like streaming vs buffering and deferred vs immediate execution.


For the most part, Skeet’s examples work well in VB.NET. One gotcha is that in VB.NET events must be associated with an instance of a class whereas Jon’s examples deal with a static (static in C# is synonymous with Shared in VB) class with static methods. Simply changing his examples to use an instance of a class allowed his examples of events to work properly. A more significant problem is the lack of support for iterator blocks with VB.NET 10 (i.e. VS 2010). This means most of chapter 6 is not directly applicable to VB. I also found the type inference in C# to be superior to VB.NET. A few of Skeet’s Linq examples had to be tweaked or explicit typing added to work properly. I found this problem mostly in determining the type of the loop variable in a For Each block. I worked through the examples using VB.NET 10 which rounds out VB.NET’s support of Lambdas. Using any earlier version of VB is likely to be frustrating. I have a nearly complete set of converted examples for those who are interested.


Now to a review of the book itself. Jon creates a narrative structure by showing the evolution of C# from the perspective of examining the language and compiler underpinnings. C# moved to language support for lambdas in two steps. First, it introduced anonymous methods in C# 2 (VS 2005) and subsequently added full lambda support in C# 3 (VS 2008). Covering both approaches is somewhat redundant for C# purposes, and even more so for VB which moved to lambda syntax without an intermediate step. Although the C# syntax is redundant, Jon’s coverage does minimize the redundancy. Don’t skip Chapter 5,which covers anonymous methods. His coverage of closure in the section on capturing variables is excellent and representative of his approach to the more challenging theoretical parts of .NET programming. Once you grasp his coverage of capturing variables, he has a nice followup article on the web here. He provides a gentle approach that warns of the complexity of the material and doesn’t get lost in academic jargon. Lambda calculus has been a favorite topic in computer science theory for many years. Jon doesn’t lose precision in his writing by trying to write in a style that is down to earth as possible. He is a stickler for consistent usage of terminology.


A key technique in the book is analyzing the code generated by the compiler. Although new language syntax has been created for C#, it is amazing just how much extra work is done by the compiler to make Linq and its underpinnings happen. Jon makes it clear what is part of the language, what are extension methods, and what is compiler magic. An important note for VB programmers is that VB does introduce more syntax directly into the language relative to C#. Jon happens to favor the C# approach which has a smaller set of syntax.


Although the focus of the book is on Linq and its underpinnings, you will learn a good deal about two crucial topics: deferred execution and functional programming. These topics will, in my opinion, reshape the future of .NET development. The increasing availability of multiple CPUs in Windows will demand that enterprise programmers take advantage of these features. Deferred execution via async enumerators has application to threading that Jeffrey Richter and the parallel processing folks within Microsoft have exploited recently, particularly in .NET 4.0. See Richter’s CLR via C# third edition for threading coverage that is all-new to readers of previous editions. Interest in functional programming has exploded in recent years and a lot of that is due to the expectation that functional programming will allow programs to be written in a way that increases parallelism. The introduction of PLinq is one way that using a functional approach to .NET can be accomplished while still using VB.NET. C# in depth will prepare you for a functional approach that, while still VB.NET is idiomatically and conceptually quite different.

Saturday, March 13, 2010

Finally, VB.NET supports Auto Properties!

One modest but greatly appreciated feature in VB 10 and Visual Studio 2010 is the inclusion of automatically implemented properties. This feature was first introduced in C# 3/Visual Studio 2008. The idea is that the typical boilerplate property declaration and creation of a field as a backing store can be created through a little extra work done by the compiler.


If you are familiar with the c# version, you will notice some differences in the VB.NET implementation. In the VB.NET version of auto properties, only properties with setters and getters having the same accessibility level. In C#, you can have an auto properties with a public getter and private setter. VB.NET does default to use Public accessibility (, although Private or Protected availability are available. A feature available only in VB.NET auto properties is the convenient ability to assign an initial default value to a property.


The full definition of a property plus its backing store looks like this.


 Private _manualProp As String = ""  
Property manualProp As String
Get
Return _manualProp
End Get
Set(ByVal value As String)
_manualProp = manualProp
End Set
End Property


The auto property definition looks like this but produces the identical code as with a manual property, if you check the results in reflector. The naming convention used is that the compiler will create a backing store field by prepending an underscore character to the name of the property.


 Property autoProp As String = “”  

For those folks committing to using a version of the .NET framework prior to 4 there is good news. Since this new feature is created through an enhancement to the compiler in Visual Studio 2010, you can still target .NET 2.0 through 3.5 and take advantage of this new feature.

Tuesday, March 2, 2010

Making a case for the NetDataContractSerializer

Despite Microsoft’s best effort to keep it a secret, the shared type contracts in the NetDataContractSerializer does have its uses, primarily internally to an application that needs to distribute itself to handle its load. WCF has distanced itself from the code-first (as opposed to schema-first) style used in ASMX web services and .NET remoting. In many cases, I concur with the arguments against the code-first approach. For dealing with other applications, even within an enterprise, it is a much cleaner design to expose an interface. The quality of the WSDL can be much better, allowing service consumers to have a quicker, less buggy development. An SOA approach to recognizing opportunities to allow asynchronous processing is definitely a better architecture to deal with load distribution, than a shared type, code first solution.


Here is a scenario that I have used to quickly make use of the NetDataContractSerializer. I have an application that exposes a web interface but is also heavily involved in EAI (enterprise application integration) scenarios. It was helpful to be able to process messages from a queue and have them processed in a scalable way using IIS and NLB (network load balancing). The open-source tool AutoMapper has opened my mind to using an interface with separate types on the client and server sides. AutoMapper takes away a lot of the grunt work in dealing with separate types that have many identically named and typed fields. Nevertheless, it is very convenient to use a common assembly and a shared type between the client and server.


To use the NetDataContractSerializer you must include in both client and server the source file for the NetDataContract attribute. Aaron Skonnard has a nice reference with the relevant source code. If you use his version just note that the name of the attribute is NetDataContractFormat whereas I chose use the name NetDataContract. Here is a VB.NET version of this:


Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.Runtime.Serialization
Imports System.Xml

Public Class NetDataContractAttribute
Public Class NetDataContract
Inherits Attribute
Implements IOperationBehavior

Public Sub AddBindingParameters(ByVal description As OperationDescription, ByVal parameters As BindingParameterCollection) Implements IOperationBehavior.AddBindingParameters

End Sub


Public Sub ApplyClientBehavior(ByVal description As OperationDescription, ByVal proxy As ClientOperation) Implements IOperationBehavior.ApplyClientBehavior
ReplaceDataContractSerializerOperationBehavior(description)
End Sub


Public Sub ApplyDispatchBehavior(ByVal description As OperationDescription, ByVal dispatch As DispatchOperation) Implements IOperationBehavior.ApplyDispatchBehavior
ReplaceDataContractSerializerOperationBehavior(description)
End Sub

Public Sub Validate(ByVal description As OperationDescription) Implements IOperationBehavior.Validate
End Sub


Private Shared Sub ReplaceDataContractSerializerOperationBehavior(ByVal description As OperationDescription)
Dim dcsOperationBehavior As DataContractSerializerOperationBehavior = description.Behaviors.Find(Of DataContractSerializerOperationBehavior)()

If dcsOperationBehavior IsNot Nothing Then
description.Behaviors.Remove(dcsOperationBehavior)
description.Behaviors.Add(New NetDataContractSerializerOperationBehavior(description))
End If
End Sub

Public Class NetDataContractSerializerOperationBehavior
Inherits DataContractSerializerOperationBehavior
Public Sub New(ByVal operationDescription As OperationDescription)
MyBase.New(operationDescription)
End Sub

Public Overrides Function CreateSerializer(ByVal type As Type, ByVal name As String, ByVal ns As String, ByVal knownTypes As IList(Of Type)) As XmlObjectSerializer
Return New NetDataContractSerializer()
End Function
Public Overrides Function CreateSerializer(ByVal type As Type, ByVal name As XmlDictionaryString, ByVal ns As XmlDictionaryString, ByVal knownTypes As IList(Of Type)) As XmlObjectSerializer
Return New NetDataContractSerializer()
End Function
End Class
End Class

End Class


The NetDataContractSerializer provides shared type information by including assembly information in the serialized message. I use this simple LocationInfo class in an assembly called SharedType.dll that isn’t strongly named to illustrate the differences in how the XML becomes serialized.

 Imports System.Runtime.Serialization  
<DataContract()> _
Public Class LocationInfo
<DataMember()> _
Public postalCode As String
<DataMember()> _
Public latitude As Double
<DataMember()> _
Public longitude As Double
End Class


My Service Contract was based on this interface.
 <ServiceContract()> _  
Public Interface INetDataContractSerializerSample
<NetDataContract()> _
<OperationContract()> _
Sub DetermineCoordinates(ByRef loc As LocationInfo)
End Interface


The default DataContractSerializer data looks like this:


 <s:Body>  
<DetermineCoordinates xmlns="http://tempuri.org/">
<loc xmlns:a="http://schemas.datacontract.org/2004/07/SharedTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:latitude>0</a:latitude>
<a:longitude>0</a:longitude>
<a:postalCode>90125</a:postalCode>
</loc>
</DetermineCoordinates>
</s:Body>

The NetDataContractSerializer data adds type information based on the shared type in the assembly. The type data includes the assembly name, assembly version, culture, and public key token.


 <s:Body>  
<DetermineCoordinates xmlns="http://tempuri.org/">
<LocationInfo z:Id="1" z:Type="SharedTypes.LocationInfo" z:Assembly="SharedTypes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://schemas.datacontract.org/2004/07/SharedTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<latitude>0</latitude>
<longitude>0</longitude>
<postalCode z:Id="2">90125</postalCode>
</LocationInfo>
</DetermineCoordinates>
</s:Body>


One gotcha I ran into in using the NetDataContractSerializer is the client not supplying type information. This results in a Protocol exception indicating that the data “does not contain expected attribute 'http://schemas.microsoft.com/2003/10/Serialization/:Type'.”. If you encounter this error, double check the client proxy file (by default reference.vb or reference.cs) in the Service References for this directory. The desired Operation Contract should have the NetDataContract attribute applied.