Sunday, August 1, 2010

Converting WCF WSDL to single file (FlatWSDL) - correctly!

Note! This post is slightly different than most FlatWSDL posts, and fixes the bug with removing the <XS-import>’s.

 

The team behind WCF chose to split all generated WSDL-definitions into multiple files, one for each namespace, schema, etc. That’s a valid approach, and most modern tools support that out of the box, it’s done correctly after the WSDL standard.

 

However, not all tools support it. Various blog posts discuss different tools, and in my case it was a mainframe integration that caused the problem. I needed to get WCF to output it as one file. The good news is that’s really simple. You can use either FlatWSDL by Thinktecture or FlatWSDL in WCFExtras (They’re almost identical).

 

The only problem is that both solutions emit a WSDL file without appropriate <XS:Import>’s for the schemas. Many tools are able to resolve the references without the import, but not all are as forgiving. This post describes a code change to WCFExtras that will fix it, but I’ll add mine here as well.

 

What you need to do is to download one of the FlatWSDL approaches (This post describes it, as well as a host of others), then change the code in ExportEndpoint in FlatWsdl.cs to what I’ve included below, and you’re good to go.

 

public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
XmlSchemaSet generatedXmlSchemas = exporter.GeneratedXmlSchemas;

foreach (ServiceDescription generatedWsdl in exporter.GeneratedWsdlDocuments)
{
var referencedXmlSchemas = FindAllReferencedXmlSchemasRecursively(generatedWsdl, generatedXmlSchemas);
ClearWsdlOfExistingSchemas(generatedWsdl);
AddAllReferencedSchemas(generatedWsdl, referencedXmlSchemas);
}

RemoveSchemaLocationFromXmlSchemaImports(exporter, generatedXmlSchemas);
}


private static IEnumerable<XmlSchema> FindAllReferencedXmlSchemasRecursively(ServiceDescription wsdl, XmlSchemaSet generatedXmlSchemas)
{
var referencedXmlSchemas = new List<XmlSchema>();
foreach (XmlSchema schema in wsdl.Types.Schemas)
{
AddReferencedXmlSchemasRecursively(schema, generatedXmlSchemas, referencedXmlSchemas);
}
return referencedXmlSchemas;
}

/// <summary>
/// Recursively extract all the list of imported
/// schemas
/// </summary>
/// <param name="schema">Schema to examine</param>
/// <param name="generatedXmlSchemas">SchemaSet with all referenced schemas</param>
/// <param name="referencedXmlSchemas">List of all referenced schemas</param>
private static void AddReferencedXmlSchemasRecursively(
XmlSchema schema,
XmlSchemaSet generatedXmlSchemas,
List<XmlSchema> referencedXmlSchemas
)
{
foreach (XmlSchemaImport import in schema.Includes)
{
ICollection realSchemas = generatedXmlSchemas.Schemas(import.Namespace);
foreach (XmlSchema ixsd in realSchemas)
{
if (!referencedXmlSchemas.Contains(ixsd))
{
referencedXmlSchemas.Add(ixsd);
AddReferencedXmlSchemasRecursively(ixsd, generatedXmlSchemas, referencedXmlSchemas);
}
}
}
}

private static void ClearWsdlOfExistingSchemas(ServiceDescription wsdl)
{
wsdl.Types.Schemas.Clear();
}

private static void AddAllReferencedSchemas(ServiceDescription wsdl, IEnumerable<XmlSchema> referencedXmlSchemas)
{
foreach (XmlSchema schema in referencedXmlSchemas)
{
wsdl.Types.Schemas.Add(schema);
}
}

private static void RemoveSchemaLocationFromXmlSchemaImports(WsdlExporter exporter, XmlSchemaSet schemaSet)
{
var mySchemaSet = new XmlSchemaSet();
mySchemaSet.Add(schemaSet);
foreach (XmlSchema schema in mySchemaSet.Schemas())
{
exporter.GeneratedXmlSchemas.Remove(schema);
}
}

Wednesday, July 28, 2010

Generating sample data for objects using AutoFixture, extending it with collections support, and using it as Silverlight sample data generator

This blog post consists of three parts

- On generating sample data in general

- Extending AutoFixture with automatic collections generation support

- Adding a sample data generator in Silverlight for Visual Studio/Blend screen previews


[Note: Windows Live Writer did a horrible job in transferring the post to the blog. I've fixed quite a bit on the formatting, but it's still in poor quality. Apologies for that. Let me know if you want the code samples without the formatting]


Generating sample data in general

Creating objects with sample data is a challenge developers often need to handle. The most common use case is for testing purposes, where you need an object with various values set. Some might be important, but many just need to be set to anything (Also called an anonymous variable).


I’ve seen and used various solutions for this. Often you see it either done manually, by an object mother, with test data builders, or by loading existing objects from a database. Many people start out writing a simple reflection tool to handle it, but stops a few hours down the road once the actual complexity involved becomes apparent.


I had a new use case for it this time, and wanted to avoid many of the problems with the solutions above. After searching for and trying various reflection based tools, I found AutoFixture, and was impressed from the get-go. It pretty much does exactly what you’d expect, and has a clean interface as well. Some examples:


- Creating an anonymous string

var anonymousText = fixture.CreateAnonymous<string>();

Result:

- anonymousText: aa48c714-6c6a-4ac4-9c27-3658c9e78d5f


- Creating an anonymous object

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

..

var personWithAnonymousData = new Fixture().CreateAnonymous<Person>();

Result:

- Name: Nameb7c2a9fc-a5b0-4836-83d9-be1b057e0ff1

- Age: 1



Take a look a the AutoFixture cheat sheat for a number of good examples. There’s many things you can do to customize the behavior and output.


That covers the introduction to AutoFixture. If you need a sample data creator, for test data or other purposes, I advice you to check it out. Over to the next point.




Extending AutoFixture with automatic collections generation support

There was one feature I was missing in AutoFixture that I really wanted. If an object has a collection (, list, or any other sort of .NET collection) of something, that collection will only be initialized to an empty collection automatically. If I do a change to the Person object and rerun, the PhoneNumbers list below will be an empty list of strings.


public  class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public List<string> PhoneNumbers { get; set; }
}


AutoFixture have functionality to handle this. If you run the line below first..


fixture.Register(() => fixture.CreateMany<string>().ToList());

..then the output of PhoneNumbers will be something similar to:

[0]: 635bc212-8d16-4029-8423-1f45016fe020

[1]: fcbed54b-94f6-4eea-b773-e7ec5e75b6dd

[2]: 814c120a-7e9c-487a-b99e-9e23d9d511b0



However, I would like this to be handled automatically. Doing it the AutoFixture-way you’ll need to know the internal structure of a class to define that it should handle a certain collection. Another problem is collection interfaces. If PhoneNumbers was defined as IList<string>, I would be forced to define it since it causes a runtime exception of:

“AutoFixture was unable to create an instance from System.Collections.Generic.IList`1[System.String], most likely because it has no public constructor.”


So I set out to see if I could extend AutoFixture to handle collections automatically. Seemed like a fun enough way of getting to know AutoFixture better as well as some good reflection fun. The requirements I set was to handle generic collections and interfaces to collections automatically.



First how to use it (Only the second line is new):


var fixture = new Fixture();
fixture.Customizations.Add(new CollectionsGenerator(fixture));
var personWithAnonymousData = fixture.CreateAnonymous<Person>();

The new CollectionsGenerator:


   1: /// <summary>
   2: /// Support for handling automatic generation of anonymous data for collections
   3: /// </summary>
   4: internal class CollectionsGenerator : ISpecimenBuilder
   5: {
   6:     private readonly Fixture _parentFixture;
   7:  
   8:     /// <param name="parentFixture">Requires parentFixture to ensure existing options are used.</param>
   9:     public CollectionsGenerator(Fixture parentFixture)
  10:     {
  11:         _parentFixture = parentFixture;
  12:     }
  13:  
  14:     public object Create(object request, ISpecimenContext context)
  15:     {
  16:         if (!ReflectionHelper.IsGenericDotNetCollectionOrInterface(request))
  17:             return new NoSpecimen(request);
  18:  
  19:         Type collectionType;
  20:         if (ReflectionHelper.ObjectIsADotNetCollectionInterface(request))
  21:             collectionType = ReflectionHelper.GetConcreteCollectionTypeToMatchInterface(request);
  22:         else
  23:             collectionType = ReflectionHelper.GetUnderlyingSystemType(request);
  24:  
  25:         var returnCollection = (IList)Activator.CreateInstance(collectionType);
26:

27:
AddAnonymousValuesToCollection(returnCollection, _parentFixture);
28:

29:
return returnCollection;
30:
}
  31:  
32:
private static void AddAnonymousValuesToCollection(IList collection, Fixture parentFixture)
  33:     {
34:
Type genericType = collection.GetType().GetGenericArguments()[0];
  35:         var createAnonymousMethod = typeof(SpecimenFactory).GetMethod("CreateAnonymous", new Type[] { typeof(ISpecimenBuilderComposer) }).MakeGenericMethod(new[] { genericType });
  36:         for (int i = 0; i < parentFixture.RepeatCount; i++)
  37:         {
  38:             collection.Add(createAnonymousMethod.Invoke(null, new ISpecimenBuilderComposer[] { parentFixture }));
  39:         }
  40:     }
  41: }


And an accompanying ReflectionHelper:

   1: public static class ReflectionHelper
   2: {
   3:     private const string UnderlyingSystemTypeString = "UnderlyingSystemType";
   4:  
   5:     public static bool CanRetrieveUnderlyingSystemTypeFromObject(object input)
   6:     {
   7:         return (input != null)
   8:                && (input.GetType().GetProperty(UnderlyingSystemTypeString) != null)
   9:                && (input.GetType().GetProperty(UnderlyingSystemTypeString).GetValue(input, null) != null);
  10:     }
  11:  
  12:     public static bool InputIsAssignableFrom(object request, Type ofType)
  13:     {
  14:         return (request != null)
  15:                && (request.GetType().GetProperty(UnderlyingSystemTypeString) != null)
  16:                && (request.GetType().GetProperty(UnderlyingSystemTypeString).GetValue(request, null) != null)
  17:                && (ofType.IsAssignableFrom((Type)request.GetType().GetProperty(UnderlyingSystemTypeString).GetValue(request, null)));
  18:     }
  19:  
  20:     public static Type GetUnderlyingSystemType(object input)
  21:     {
  22:         return (Type)input.GetType().GetProperty(UnderlyingSystemTypeString).GetValue(input, null);
  23:     }
  24:  
  25:     public static bool ObjectHasGenericTypeSpecified(object input)
  26:     {
  27:         return GetUnderlyingSystemType(input).IsGenericType && GetUnderlyingSystemType(input).GetGenericArguments().Length > 0;
  28:     }
  29:  
  30:     public static bool IsGenericDotNetCollectionOrInterface(object request)
  31:     {
  32:         if (!CanRetrieveUnderlyingSystemTypeFromObject(request))
  33:             return false;
  34:  
  35:         return    (ObjectIsADotNetCollection(request) || ObjectIsADotNetCollectionInterface(request)) 
  36:                && (ObjectHasGenericTypeSpecified(request));
  37:     }
  38:  
  39:     public static bool ObjectIsADotNetCollection(object request)
  40:     {
  41:         return InputIsAssignableFrom(request, typeof(IList));
  42:     }
  43:  
  44:     public static bool ObjectIsADotNetCollectionInterface(object request)
  45:     {
  46:         var objectTypeName = GetUnderlyingSystemType(request).ToString();
  47:  
  48:         var dotNetCollectionTypes = new List<string> //.NET Collections
  49:                     {
  50:                     "System.Collections.Generic.IList",
  51:                     "System.Collections.Generic.IEnumerable",
  52:                     "System.Collections.Generic.IEnumerator",
  53:                     "System.Collections.Generic.ICollection",
  54:                     "System.Collections.Generic.ISet",
  55:                     "System.Collections.IList",
  56:                     "System.Collections.IEnumerable",
  57:                     "System.Collections.IEnumerator",  58:                     "System.Collections.ICollection", 
  59:                     };
  60:         
  61:         return dotNetCollectionTypes.Any(objectTypeName.Contains);
  62:     }
  63:  
  64:     public static Type GetConcreteListTypeToMatchInterface(object request)
  65:     {
  66:         Type genericType = GetUnderlyingSystemType(request).GetGenericArguments()[0];
  67:  
  68:         string genericListTypeName = "System.Collections.Generic.List`1"
  69:                                      + "[[" + genericType.AssemblyQualifiedName + "]]"
  70:                                      + ","
  71:                                      + Type.GetType("System.Collections.IList").Assembly.FullName;
  72:         return Type.GetType(genericListTypeName);
  73:     }
  74: }



Note that this isn’t release quality. There’s a few issues, like with recursion if a complex type contains an instance of itself, and the way .NET collections are identified.



Adding a sample data generator in Silverlight for Visual Studio/Blend screen previews

The actual use case I was trying to solve was creating automatic sample data for XAML pages in Silverlight. This would enable me to better see how pages looked in Visual Studio and Blend, and a way of testing data bindings as well.


Note that AutoFixture doesn’t support Silverlight just yet, but there is a fork available that supports it (If you want to use a newer version, you only need to do a couple of changes to trunk to make it work).


I wanted a more natural interface for the sample data, so I created a SampleDataGenerator class:


   1: /// <summary>
   2: /// Creates sample data for object or collection of objects recursively
   3: /// </summary>
   4: public static class SampleDataGenerator
   5: {
   6:     public static T GenerateObjectWithData<T>()
   7:     {
   8:         return CreateFixtureWithDefaultSetup<T>().CreateAnonymous<T>();
   9:     }
  10:  
  11:     public static T GenerateObjectWithData<T>(int collectionItemAmount)
  12:     {
  13:         var fixture = CreateFixtureWithDefaultSetup<T>();
  14:         fixture.RepeatCount = collectionItemAmount; //Object count generated per list
  15:         return fixture.CreateAnonymous<T>();
  16:     }
  17:  
  18:     public static IEnumerable<T> CreateMany<T>()
  19:     {
  20:         return CreateFixtureWithDefaultSetup<T>().CreateMany<T>();
  21:     }
  22:     public static IEnumerable<T> CreateMany<T>(T seed)
  23:     {
  24:         return CreateFixtureWithDefaultSetup<T>().CreateMany(seed);
  25:     }
  26:  
  27:     public static IEnumerable<T> CreateMany<T>(int count)
  28:     {
  29:         return CreateFixtureWithDefaultSetup<T>().CreateMany<T>(count);
  30:     }
  31:  
  32:     public static IEnumerable<T> CreateMany<T>(T seed, int count)
  33:     {
  34:         return CreateFixtureWithDefaultSetup<T>().CreateMany<T>(seed, count);
  35:     }
  36:  
  37:     private static Fixture CreateFixtureWithDefaultSetup<T>()
  38:     {
  39:         var fixture = new Fixture();
  40:         fixture.Customizations.Add(new StringGenerator(() => ""));
  41:         fixture.Customizations.Add(new CollectionsGenerator(fixture));
  42:         return fixture;
  43:     }
  44: }

At the bottom of the code above I have included use of the CollectionsGenerator class. I also changed the default behavior of StringGenerator, so it only outputs the property name instead of property name + guid.


You can then use it in a sample object that inherits the ViewModel:


 1: public class EditPersonSampleData : EditPersonViewModel
2:
{
3:
public EditPersonSampleData()
4:
{
5:
Person = SampleDataGenerator.GenerateObjectWithData<Person>();
6:
}
7:
}


And then in the EditPersonView.xaml, include:

 1: xmlns:vm="clr-namespace:SomeNamespace.EditPerson" 
2:

3:
...
4:

5:
<Grid x:Name="LayoutRoot" Background="White" d:DataContext="{d:DesignInstance Type=vm:EditPersonSampleData, IsDesignTimeCreatable=True}">
6:


That’s all you need to get sample data visible in a XAML viewer. Good way of checking that the interface looks OK and that the binding is set up correctly.


Vote here to get similar support in the actual AutoFixture product.

Saturday, January 23, 2010

Changes in software – Different developers over time for a long-running project

To do changes to software you need to understand it. You need to understand the exact piece of code you are changing, you need an overview of the system to be aware of any dependent parts, and you need to understand the technologies in use. In the real world you can also end up with a few more difficulties. You need to understand why things work the way they do. Will the changes you are imposing break existing logic? Does any clear documentation of how things work exist, or that you'll need to update? Can you trust the documentation that does exist?


Once you have a "long-running project" you get the added difficulty of handling information stored only in a developers or business specialists head. Your best option is to have the same developers working on the project for its lifetime. That can be challenging in terms of getting the right people in on it. When that's not possible you need to make sure you don't end up in a situation where the knowledge is lost.


The state of the actual code is perhaps the most important. Documentation will always be hard to keep up to date, and the best description of what you have is your code. It's essential that it is well structured and readable to make changes possible. Do refactorings when it helps clarify code, or when your understanding of the problem or domain changes. Write small and well named automatic tests that each verify a single piece of behavior and explains why and in what context. For this context, the tests will help clarify how a piece of code works and is intended to be used (Do you know what AAA is? If not, it's about time you do).


Consider increasing the truck factor of your code - meaning, how many people must be hit by a truck before a piece of information is lost. This has a lot to do with how you handle code ownership. Does individuals only make changes in their piece of the code, are there module leaders that supervise changes to parts of the system, or do you have a form of collective code ownership (XP's view on collective ownership: http://www.extremeprogramming.org/rules/collective.html)? Like every part of software development, there is no answer that is correct in every situation, but strong individual ownership is most likely to cause problems in my view. The truck factor is extremely low, a sort of "me versus they" mentality can lead to things falling between two chairs. Few developers knowing a piece of code means fewer can do changes to it if problems arise, and different parts of a system can end up being developed quite differently.


Documentation is another area. Do you document at all? Only high level requirements? Sequence or collaboration diagrams? Is the documentation kept up to date? No business decisions hidden in mail discussions or in developer or business users heads? In meeting minutes? This is such a tough area. I haven't quite made up my mind about this yet - but I do know one thing - keeping documentation truly up to date is extremely challenging. You can certainly try to document everything, but is it worth it in terms of ROI?


When a developer do choose to leave a project, make sure you work to capture as much knowledge as possible. Hopefully most of the knowledge of the developer is already shared with the team, but try to capture the rest as much as possible. It will cost a lot more to try and understand something later on.

Sunday, January 17, 2010

Changes in software - One of the biggest challenges of software development

Changes to software has been a problem since the dawn of computers, and it still is a challenge with every piece of software developed. Perhaps the biggest part of creating software is changing or expanding existing code. So handling changes is something we have to deal with all the time. It's the maintainability aspect of software development. The problem is that there are so many challenges involved, so many things that can go wrong. But do you know what the worst problem is? The fact that a lot of developers have very little focus on the issue in general, including the reasons behind it.


I tried to come up with a few of the top of my head, and listed almost thirty easily (Even without going into nitty gritty coding issues). No wonder it's hard to handle. There's no silver bullet to fix many of these issues, but as with everything else in life - you need to know about it to be able to do something with it.


Here's a number of things that affects and complicates changes in software:

Project

  • Many different developers over time
  • Legacy codebase
  • External system dependencies

Person

  • Developer with limited understanding of code in general
  • Developer with limited understanding of the projects code and architecture
  • Unmotivated developer
  • Changes done just before end of day/end of week/end of year
  • Different quality of developers
  • Misunderstanding the time it takes to write quality code
  • Not thoroughly understanding a problem

Code

  • The danger of quick fixes/hacks
  • Lack of understanding of how software rot
  • Unreadable code.
  • High coupling in the system. Making a change in code that is used many places has a higher risk.
  • Complex architecture (Hard to understand or wrong for the problem at hand)
  • Duplicate code

Business

  • Illogical business logic
  • Unavailable business people

Process

  • Time (Quality - if time permits)
  • Bug acceptance
  • Developer not feeling the pain of fixing production bugs
  • Task-switching developer
  • Picking up problems caused by changes
  • Lack of testing
  • Big bang releases / seldom releases
  • Individual code ownership
  • Refactoring / Not refactoring
  • Adding additional features at end of test/iteration/project

This post would get way too long if I were to cover all the reasons in detail, so I'm rather going to cover various individual ones in separate posts.

 

Did you miss something on the list?

Thursday, January 14, 2010

Real programmers don't comment their code. If it was hard to write, it should be hard to understand

Now that's just a plain lie. Real programmers do comment their code - though only certain parts of it.

First of all, an important rule: Your code should be so readable that you don't need comments to understand what it does.

Comments are a problem because they
- might not get get updated when the code changes.
- become an excuse to write unreadable code.

If you can't trust that the comment is correct, you'll have to go into a method to understand what it does. Once you do that you might have to step even further down into other methods, and soon you'll forget what you were doing initially.

Justifying unreadable code with comments is heresy. You should not need to write comments to explain what a piece of code does. What do you need to do if you have code that does need additional comments? Refactor! Often the text you would put in comments can be used as method names instead. Don't forget Joshua Kerievsky's tip in Refactoring to Patterns:

"What is the preferred size of small methods? I would say ten lines of code or fewer, with the majority of your methods using one to five lines of code. If you make the vast majority of a system's methods small, you can have a few methods that are larger, as long as they are simple to understand and don't contain duplication."

 

Don't be afraid of small methods with a readable signature. You have intellisense to help finish method names, and the performance hit of having many methods is negligible, so none of those arguments hold any value. Does it feel like your classes end up with too many methods? There's a good change they're doing too much. Remember to use the Single Responsibility Principle on both classes and methods - they should be responsible for doing only one thing, and should have one, and only one, reason to change.

 

When are comments appropriate?
- At major boundaries, for instance with libraries or at service contracts, giving context or similar.
- Clarification or expressing intent, if you fail to do it in code
- Warnings or particular notifications
- Regular expressions, if you have to use them
- TODO's, sparingly.
- When you have no other options.

There is always a need for comments in you code. The rule should be to not use them, but if you have a good reason - go right ahead.

I think Uncle Bob says it well in Clean Code:

"The proper use of comments is to compensate for our failure to express ourself in code. Note that I used the word failure. I meant it. Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration. [...] Every time you express yourself in code, you should pat yourself on the back. Every time you write a comment, you should grimace and feel the failure of your ability of expression."

Sunday, January 10, 2010

Object Orientation revisited – Business layer patterns

Object orientation is a fascinating topic. It is one of the core concepts for a major part of developers today, yet the understanding and the inclusion of it in our day to day work varies greatly. Even though many believe they do the same. 'Cause everyone is working object oriented with an object oriented language, right?


We had a day back in December at Objectware where we revisited object orientation, and its implications for our work. The day was structured with some presentations first, a good deal of group work, a reflection on the work, followed by a general discussion in the end. We had a continuous focus on discussions and experience sharing throughout. I started of with a session on general everyone-should-know information, more of a recap or introduction if you will, and then brought the focus to the use of object orientation in structuring our business logic, centralized or delegated design, and so on. A few colleagues of me followed on with topics concerning cohesion and coupling, information hiding and composition vs inheritance.


I thought I'd share some of the content of my presentation here. It's certainly not a new topic, it has been blogged and written about countless times, but still I meet a lot of variation on the knowledge in this area.


First of all - how is this valuable to you? Knowing how to structure your business logic both in various forms of applications, but also varying internally in an application, is paramount in ending up with an application that doesn't fight you continuously. In designing every application we want to:

  • Create an architecture that meets all technical and operational demands
  • AND that solves all quality attributes like performance, security and maintainability well


The architect should set standards concerning the business logic layer, but I've seen more than one architecture transform into something very different because of varying knowledge on this. It's always important to know the main differences so you can take informed decisions. This is one of those areas that most software developers should know - especially those that work on applications containing more than a trivial amount of business logic.

 

Introducing OO

Object orientation is about core principles like abstraction, composition, inheritance, encapsulation, polymorphism and decoupling. Several things can be said about this style of programming, like

Division of responsibilities for an application or system into individual reusable and self-sufficient objects, each containing the data and the behavior relevant to the object.”


”An objectoriented design views a system as a series of cooperating objects, instead of a set of routines or procedural instructions.”


In general it can be said that Object Orientation should be considered when:


”You want to model your application based on real world objects and actions, or you already have suitable objects and classes that match the design and operational requirements. The object-oriented style is also suitable if you must encapsulate logic and data together in reusable components or you have complex business logic that requires abstraction and dynamic behavior.”


(All quotes from Microsoft Application Architecture Guide, 2nd Edition)


And you continuously work to

  • find the right abstraction of the real world for your problem
  • find fitting objects
  • find the right place to put code
  • rework the code at all times to make sure it is correct based on your current understanding
  • favor low coupling
  • limit duplication
  • make each object work on one thing only - ensuring high cohesion
  • work to have a test friendly design 
  • and generally try to keep your code as to-the-point as possible, all the time ensuring that adding further behavior and extending the current functionality is as painless as possible (without over engineering of course :) )
  • and certainly much more than this..


How you structure your business layer certainly has a say in how well and how easily you can achieve these things.
You traditionally have four main ways of structuring this logic:


Procedurally oriented with Transaction script or Table module.
or
Object oriented with Active record or Domain model.

Let's take a closer look at each..

 

 


Transaction script

 

”Organizes business logic by procedures where each procedure handles a single request from the presentation.”

Martin Fowler, Patterns of Enterprise Application Architecture



Transaction script follows the current structure:



Note that this is an extremely simplified example. Using transaction script you certainly utilize all you know about class design and move logic into where it fits best, the main point I'm trying to make is that you have a central place to control the flow. The CreateOrder method controls what logic will happen from start to end.


If you use this all the way, the business layer will consist of a number of procedures that each implements one action from the user interface. Good design in this context is about minimizing duplication at the same time as meeting all demands. This has nothing to do with a database transaction, but refers to one monolithic logical operation. It is not uncommon to create one business component per database table.


The positive sides with it is that it's easy to understand and maps well to the flow of a user story/use case. But it breaks down on complicated logic, can be hard to test as it does many things, and can lead to duplicated code.
Being popular in general, it the .NET world it was quickly replaced in popularity by....

 

Table module

 

”A single instance that handles the business logic for all rows in a database table or view.”

Martin Fowler, Patterns of Enterprise Application Architecture



The Table module is built around a table of data. Its perspective is similar to that of Table script, except the focus is on a group of data. Operations are often designed as methods on an object that represents a table of rows. Because of that you always use a key or index to indicate the row in use. It is procedural, but has more of an object oriented focus than Transaction script.
Note that you don't need to encapsulate the DataSet in a custom class, it is common to just work directly with the DataSet as well.


Table Module quickly became a success in .NET because of the great tool support existing. Putting together a simple read-only application that shows data in grid form literally takes no time because of the focus Microsoft has had on the tooling aspect. Everything from GUI to database works smoothly for this. Generally you can say that RAD applications work great with this approach. And it's a fair compromise if you have little logic and don't need much abstraction over you data model - because there will be a very tight coupling between your data model and every part of the application.


A history lesson

The Table module pattern has many downsides though - even in .NET. If you have complex business logic, it won't cope with that very well. It's very data driven, and doesn't focus on the business side of things. You will end up with an application that is very tightly coupled to the database. It is poor at indicating relationships between objects, and polymorphism isn't exactly available. As long as you keep to the code generation and wizard support available, you'll be all right, but it can get complicated if you can't rely on that.


Microsoft had for many years an almost exclusive focus on this pattern - by their way of action basically saying that you could solve any problem with a dataset. Object bigots found various ways around it, often by creating mappers that converted datasets to objects, by cleverly encapsulating datasets or by creating custom data mappers using the data reader directly. The focus since Visual Basics heyday was on RAD applications, supporting novice developers, and not all that much more (Patterns & Practices shipped Enterprise Library 1.0 in 2005 though). The Microsoft community didn't seem to mature much more either, as there was an almost sole focus on software and tools that Microsoft shipped. From what I have come to understand this made the whole community much less used to object orientation than for instance the Java community became. And that is likely the main reason why the general Microsoft community is still so procedurally oriented still.


Luckily things have changed, both in terms of third party tools and to some extent Microsoft's focus. Tools like NHibernate and the Castle Project led the way with support for good object relational mapping and dependency injection tools, as well as MonoRail as an early MVC framework. Microsoft has supported enterprise applications through the work of Patterns and Practices on Enterprise Library. However, simplicity and enterprise library has never been used in the same sentence. In recent times though, Microsoft begun focusing on object relational mapping through LINQ To SQL and Entity Framework, an own MVC framework, ASP .NET MVC and their own IoC container, Unity, and the continuing support for composite UI applications with PRISM for WPF and Silverlight (Following the Composite UI Application Block for Winforms).


So the tide has to some extent turned in the Microsoft community, certainly the support for the two remaining patterns are continuously improving.


But less take a closer look at the object oriented patterns:

 


Active Record

 

”An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.”

Martin Fowler, Patterns of Enterprise Application Architecture

 

  


The example above uses Castle Active Record. As you can see, the object encapsulates one database row in principle, and the object contains both data and domain logic. It includes logic to directly manipulate the database, like Save or Delete, and also includes static methods that work on the entire collection, like Get, or GetOrdersCount.


The flow of logic is different in Active Record than in the two previous patterns in that the object contains the logic internally, making use of encapsulation and achieving higher cohesion. Instead of having the service dictate how the logic should flow, you ask the object to perform some domain logic, and although not shown here, it typically delegates responsibility to other objects.


Active Record is a useful framework for two reasons: simplicity and tooling support. It's quite easy to understand, and as long as you use frameworks like Castle Active Record or LINQ to SQL, it's also fairly easy to use. For simple object models it works great, and as long as it's OK to have the object model closely mimic the data model, Active Record is a good choice.


There's a few things you should consider before choosing Active Record though. Because of it's close connection to the data model, you have very limited support for designing your object model separate of the database. If you have a need for that, you should skip ahead to the next pattern. It's also a problem that it mixes responsibilities. The objects holds domain data and methods, but in addition you have attributes for mapping to the database, CRUD operations and static methods that work on the entire collection. And it sure isn't Persistence Ignorant (PI).


This is a popular pattern as well, and even though it seemed Microsoft tried to kill (http://bit.ly/8VkYnW) LINQ to SQL to avoid supporting it in addition to Entity Framework (more on this tool later), it's popularity seems to have saved it for now.
If  Active Record doesn't quite do it for you, and your complexity is high enough, you should take a closer look at the next pattern:

 


Domain Model

 

”An object model of the domain that incorporates both behavior and data”

Martin Fowler, Patterns of Enterprise Application Architecture



The domain model pattern is the one that best supports object orientation. The point is to separate the domain logic into classes that are only concerned with modeling the domain and the corresponding rules well. The model classes should not know how to persist themselves (as in Active Record) and shouldn't be coupled to infrastructure logic. The classes should be POCO (Plan Old CLR Object), enabling a higher abstraction from the data model. This also means that the business logic of the domain model is simple to test, and you can easily get high coverage on this most important area without worrying about infrastructure and the like.


Domain model is the most complex to use, mostly because of the cost relating to mapping to the database (because of the impedance mismatch), and complexity regarding new ways of having to think about disconnected objects, lazy loading, less direct SQL to tweak and converning the next major point of this blogpost, not being familiar with delegated control. This complexity is biggest on first usage, and drops in subsequent projects.

Domain model shouldn't be used in all scenarios. Use it when you have a complex domain with complex business rules and when you want to be able to model the domain model free from database limitations. It is more complex to master than the other patterns, but in the right scenarios has great strengths.


To handle the persistence of your domain model you use an Object Relational Mapper (OR/M). This includes an API for CRUD operations, mapping between the database and the data and domain model and a query model and associated language. The modeling is usually done either via external XML mapping files or some kind of fluent interface, where you state how the model maps to the database. A lot can be said about Object Relational Mappers, but this is not the place. One thing though - various people have objections against using domain model and object relational mapping for the wrong reasons. Be skeptical about objections concerning security, performance and SQL injection. More on that another time.


Much has been said about domain models. In recent years, the most influential books on the topic have been Martin Fowler's Patterns of Enterprise Application Architecture and Eric Evans' Domain Driven Design.

 


Centralized or delegated control

If you take a look at sequence diagrams of logic designed as the two procedural patterns, transaction script and table module, compared to the object oriented ones, active record and domain model, you will see two quite different information flows. The procedural ones uses a centralized control style, whereas the object oriented ones use a delegated one.


The logic for transaction script or table module is controlled from one location. The script knows which steps the transaction needs to take to perform the task, and asks appropriate helper classes to solve each step. A sequence diagram will show you information going into helper classes, often with single parameters or a form of DTOs, and back again, then into new classes, and so on. You have a central point of control.


Active record and domain model works in a different way. Here the responsibility is typically delegated to one or more objects, which again delegates responsibility to other objects. A sequence diagram will show you a flow going into an object, then delegated into other objects, and so on, instead of going back and forth from the central location. In this way you have a delegated form of control.


I think the procedural, or centralized control style, is more common in .NET than in Java. The main reason is the support and focus that Microsoft has had.A research paper was published in IEEE Transactions on Software Engineering, called "Evaluating the Effect of a Delegated versus Centralized Control Style on the Maintainability of Object-Oriented Software", where about 150 senior, intermediate and junior developers, including a number of students, participated. The developers had to make various changes in both a delegated and a centralized design. The results:


"The results show that the most skilled developers, in particular, the senior consultants, require less time to maintain software with a delegated control style than with a centralized control style. However, more novice developers, in particular, the undergraduate students and junior consultants, have serious problems understanding a delegated control style, and perform far better with a centralized control style".


And then concluding:


"Thus, the maintainability of object-oriented software depends, to a large extent, on the skill of the developers who are going to maintain it. These results may have serious implications for object-oriented development in an industrial context: Having senior consultants design object-oriented systems may eventually pose difficulties unless they make an effort to keep the designs simple, as the cognitive complexity of 'expert' designs might be unmanageable for less skilled maintainers."


I think the conclusions with the delegated style of control also has a lot to do with familiarity. Since many .NET developers, including senior ones as well, have limited experience with this, imposing a delegated style can take some time getting used to.

 


Have I covered everything then?

Since I put the heading in here, I'm sure you already know the answer to the question. There is one pattern I haven't mentioned yet, or an anti-pattern anyway. And a common one, that is.


I've mentioned several times in this post how the .NET community often have had a procedural focus. I think that is the reason why this pattern seem to be so popular in .NET-land. Let's have a closer look at what I'm talking about.

 


Anemic Domain Model

The Anemic Domain Model looks like a domain model, has a rich structure of objects, but there's almost no behavior in the objects. The logic is typically controlled via a transaction script, with the model being simply data containers.


 


The examples are Hello World in complexity, but hopefully still captures the main difference between this and a regular domain model. As you can see, the logic has mostly been moved out of the domain model, and into a different class. It's quite common that these are referred to as xxHelper, xxManager, xxHandler, or other general terms.


This (anti-)pattern can be easier to understand for those struggling with delegated control, but this is a benefit with a cost. Other benefits is that you can brag about having a domain model to your friends (which you don't), and any other benefits you get with transaction script. The problem is that you get the same problems as with transaction script - a challenge with complex code, duplication of code and logic that is harder to unit test. In addition you get the complexity of using an OR/M on top of that.

 


Conclusion

None of these patterns is never right. That's part of the fun of software development. You need to take a close look at what you need to build and then take an informed guess. Take into account the positive and negative sides, and when you have made the choice - make real effort to diminish the effects of the negative sides.