So what pattern is this

I was working with Rob Seder on an interesting problem.  I have a 3rd party assembly that I am writing a façade over – this façade will be used by other developers in their applications.  Because of licensing, the 3rd party assembly cannot be installed on workstations.  The assembly can be installed on a WCF service that applications can then call – a façade calling another façade.

Following the ADO.NET model, we created a Connection that inherited from DBConnection and a Command that inherited from DbCommand.  My initial thought was to create two different commands that reflect the different connection methods: a WebServiceCommand and a DirectCallCommand with the individual implementations in each command’s ExecuteScaler() method.  Each command would take in a connection that that is specific to the connection type.

After some discussion, we decided to do the opposite.  We created an interface for the connections that have 1 method, Execute, and that takes in the type of command needed.

interface IFooConnection
{
    object Execute(FooCommand command);
}

The FooCommand derived from DbCommand and newed the Connection property:

image

 

We then created two connections that implement the IFooConnection interface, for example:

image

and

image

 

In the execute method, we implemented the connection-specific code.  The WebService call in the FooWebServiceConnection and the direct API calls in the FooDirectCallConnnection.

Then, we overrided the FooCommand ExecuteScaler, that calls the connection’s specific implementation:

public override object ExecuteScalar()
{
    return this.Connection.Execute(this);
}

I like this solution because it is extensible – new kinds of FooConnections come in, we just have to create specific implementation in the Execute method.  I have some questions in my head:

  • Does this follow any established design-pattern?  I re-read the GOF book this AM and could not find one that matched.
  • Is this an example of any SOLID principle?
  • Is this an example of Dependency Injection?
Advertisements

Domain Specific Language and POCOs

I was thinking about POCOs last night and how they relate to the Ubiquitous Language Principle*.  To illustrate my thoughts, I created a simple 3-tier solution ins Visual Studio.  The User Layer is a Console Application that references the Business Layer.  The Business Layer then references the Data Layer.  The Data Layer uses Entity Framework to handle all of the CRUD with the actual database. 

 

image

 

Following good design, I know that my POCOs need to represent the domain objects that the application is acting on.  I also know that these domain objects need to be defined only once.  Also, because of the dependencies, the EF created classes should not be visible to the User Layer – if the UI references the data layer, then the simplicity of design and the chance of circular relationships and twisted logic increases significantly. 

Following that path, I created a POCO in my data layer.  I started with a Category Class:

image

Note the naming difference among properties between the Business Layer Category Class and the Data Layer Category Class.  I then wired up a CategoryFactory class that provides new Categories and acts on changes to altered categories – sort of a mish-mash between the GOF Factory and Builder pattern and the more-recent Repository pattern.

The first method I wrote was a select by id method:

public Category GetCategory(int id)
{
    NorthwindEntities entities = new NorthwindEntities();
    entities.Categories.Where(c => c.CategoryID == id).FirstOrDefault();
    return null;
}

The problem is immediately apparent.  I am selecting a Northwind.Data.Category from the data layer but I am returning a Northwind.Business.Category from the business layer.  I need some kind of translation method to handle the 2 classes.

public Category GetCategory(int id)
{
    NorthwindEntities entities = new NorthwindEntities();
    Northwind.Data.Category dataCategory = entities.Categories.Where(c => c.CategoryID == id).FirstOrDefault();
    return ConvertCategory(dataCategory);
}

private Category ConvertCategory(Northwind.Data.Category dataCategory)
{
    Category category = new Category()
    {
        Id = dataCategory.CategoryID,
        Description = dataCategory.Description,
        Name = dataCategory.CategoryName
        //TODO: Convert byte[] to picture 
    };
    return category;
}

This kind of solution introduces lots of code, which can be fixed using a POCO generator.  I still have a problem though – does having a Category in each layer violate the Ubiquitous Language Principle?  If you read Even’s description, the answer is “maybe” – he introduces the ULP so that business people can be specific in their requirements and talk in terms of the domain model.  Should the business experts even know about the data layer – probably not.  But what about 2 different sets of developers on the team – the business layer developers and the data layer developers?  When they talk about a Category in a meeting, which one?  Should they namespace it?  How about if we add the dbas to the meeting?  Their category is the actual representation on the database, which may or may not directly correspond to the data layer category which may not correspond to the business layer category.  Finally, what happens when the business expert talks to the dbas (a common occurrence when the reporting module is being developed separately).  The business expert might be talking Northwind.Business.Category and the dba is talking a Category table record. 

I don’t have a good solution, or even a good set of possible options:

1) Give every object a name that reflects not only their business meaning but their layer with the Cannon being the business layer.

CategoryDataTable

CategoryDataObject

Category

Yuck. And do you want to tell the DBA/Data Modeler that they have to rename their tables?  Good luck.

2) Always talk in namespaces in meetings.  For example. “Hey Joe, I noticed that the Data.Category object has a Description field.  Is it read-only?”  The Business.Category is not.  Less yucky, but requires a more specific lexicon that might drive your business experts nuts.  Also, note the variable name that I used in the transform method (dataCategory) – it is not really Hungarian notation because I am not using the type in the prefix, but I am using the namespace.  Yuck.

3) I don’t have an option #3.

As it stands, I option for #2 – I would rather be specific with my business experts and use some kind of Hungarian-notation bastardization. But I am not happy….

 

*   The Ubiquitous Language Principle is something I coined after reading chapter 2 of  Eric Evan’s Domain Driven Design

The Coolness Of Inheritance

I was writing a simple request/response to a non-WCF web service.  The service’s request SOAP looked like this:

<?xml version="1.0" encoding="utf-8" ?>
<WorkItem AppName='TBD'>
  <UserName nametype='familiar'>Jamie</UserName>
  <UserItem>Pencil</UserItem>
</WorkItem>

created some classes that matched the request:

[Serializable]
public class WorkItem
{
    [XmlAttribute(AttributeName="AppName")]
    public string ApplicationName { get; set; }
    [XmlElement]
    public UserName UserName { get; set; }
    [XmlElement]
    public string UserItem { get; set; }
}

and

[Serializable]
public class UserName
{
    [XmlAttribute(AttributeName = "nameType")] 
    public string NameType { get; set; }
    [XmlText]
    public string Value { get; set; }
}

I then created a function that populates these classes with the data:

static WorkItem CreateWorkItem()
{
    WorkItem workItem = new WorkItem();
    UserName userName = new UserName();

    userName.NameType = "familiar";
    userName.Value = "Jamie";

    workItem.ApplicationName = "TBD";
    workItem.UserName = userName;
    workItem.UserItem = "Pencil";

    return workItem;
}

Finally, I created a helper function that takes the classes and serializes them as XML:

static XmlDocument CreateXMLDocument(WorkItem workItem)
{

    XmlSerializer serializer = new XmlSerializer(typeof(WorkItem));
    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
    namespaces.Add(String.Empty, String.Empty);
    StringWriter stringWriter = new StringWriter();
    serializer.Serialize(stringWriter, workItem, namespaces);
    stringWriter.Close();

    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.LoadXml(stringWriter.ToString());
    return xmlDocument;
}

When I run it, things look great… except that the Encoding is wrong:

image

The path of least resistance would be to set the Encoding property of the StringWriter class.  However, that property is read-only.  After playing around with the different classes in System.IO that expose encoding (usually though the constructor), I stumbled upon this great article.  The easiest way to get UTF-8 encoding in a stringWriter is to override the default implementation in the constructor.  I went ahead and created a new class and overrode the Encoding property.

public class UTF8StringWriter : StringWriter
{
    Encoding encoding;
    public UTF8StringWriter()
        : base()
    {
        this.encoding = Encoding.UTF8;
    }

    public override Encoding Encoding
    {
        get
        {
            return encoding;
        }
    }
}

Note that I used a local variable.  Thank goodness the StringWriter uses its property (not a private variable) in the Serialize method.  A big thank you to whoever wrote that class in a proper way.  I then changed the stringWriter variable to a UTF8WringWriter like this:

UTF8StringWriter stringWriter = new UTF8StringWriter();

The output now renders correctly:

image

XML Code Comments

 

I made a new-years resolution* to learn more about XML code comments and the associated language – MAML.  To that end, I installed Sandcastle and the Sandcastle Help File Builder  – now found here and here.

I then when to one of my many “Hello World” projects laying around my file system.  The sum total of the project is this:

public class Program
{
    public static void Main(string[] args)
    {
        WriteMessage("Hello World");
        Console.ReadKey();
    }

    public static void WriteMessage(string input)
    {
        if(String.IsNullOrEmpty(input))
        {
            throw new ArgumentNullException("Input cannot be empty.");
        }

        Console.WriteLine(input);
    }
}

Note that the scope of the class and methods are public.

I then went into project properties and checked off  XML Document file:

image

I then hit F6 and….

image

How cool is that?  VS2010 tells you if you are missing comments – it keeps track of things so you don’t have to.  So now I have to add some comments.  I went above the class and hit /// and presto-chango, I get an awesome block of code comments.  The other nice thing about this snippet is that if there are parameters, that gets pre-filled for me.  For example, the WriteMessage snippet looks like:

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>

I then went ahead and added code comments to that method:

        /// <summary>
        /// Writes a message to the console window.
        /// </summary>
        /// <param name="input">The message to be written.</param>
        /// <exception cref="ArgumentNullException">If the input is null or empty.</exception>

Note that when you hit ///, you get an option of a bunch of different kinds of comments.  A full list for is found here.  Also note that my comments are all in grammatically-correct English with punctuation.  Finally note that I use param for the input, not paramref in the summary…

I then added a class-level comment and changed the scope of Main.  I hit F6 and I now have an XML code comment file created and ready in my bin directory.

image

I then loaded up Sandcastle Help File Builder and created a new project:

image

I then added a reference to the XML file that was generated by Visual Studio Project Explorer-> Documentation Sources –> Right Click Add.  Then, I hit Build (the two down arrow button) and magic happened – right in front of my very eyes. 

image

Opening up the .chm file, I got full-blown help file. 

image 

There was one problem, as you can read in the output from SHFB:

Warn: ShowMissingComponent: Missing <summary> documentation for N:Tff.VisualStudioBuildExample

And in the help file:

image

To get around this, I first started trying to add another XML file in addition to the one that VS2010 generated – a XML Document File – You can read about it here.   I futzed around with it for a bit and then gave up.  I then just added the values a properties in SHFB here:

image

Clicking on the ellipses, you get this dialog where you can enter in your summaries:

image

And then you get the namespace comments:

image

 

* Nepali New Year is celebrated on the 1st of Baisakh Baisākh (12–15 April) in Nepal. Nepal follows Vikram Samvat (विक्रम संवत्) as an official calender. (Not to be confused with Nepal Era New year).  Thanks Wikipedia!