Condividi tramite


Fluent Interface for System.Identity – Kind’s Expression Builder

<Author’s Note>

It’s been quite a while since my last blog post. The reason for the gap was due to my non-work time being consumed with swimming (some might say wallowing ;-) in the architectural soup writing a ThinkWeek paper related to Microsoft IT (MSIT) software architecture. Writing the paper took quite a bit more effort than I expected, but I found it a highly enjoyable exercise (yes, I know, I have no life). Now that the paper is done, I’m back to finishing up this series on System.Identity.

</Author’s Note>

The last post in this series finished up some of the plumbing aspects of the System.Identity fluent interface, focusing on the impacts of persisting the fluent interface to the Oslo Repository on the implementation of the Equals() and GetHashCode() methods inherited from System.Object. With the details of the ORM persistence for the fluent interface and the definition of the Kind class’ Command-Query API taken care of, it’s time to take a look at the Kind Expression Builder.

 

A Method Chaining Builder for Kinds

The Expression Builder that will be explored in this post is a class that provides a fluent interface for the construction of Kind objects through the use of Method Chaining. Specifically, the desirable end state is for the code that creates Kind objects to look like the following:

    1: Kind kind = new KindBuilder ()
    2:     .IsNamed ( "TestKind" )
    3:     .CanBeDescribedAs ( "SomeDescription" )
    4:     .CanBeIdentifiedByTheKeywords ( "Keyword" )
    5:     .IsStoredInFolder ( 250 )
    6:     .IsOwnedBy ( owningParty );

 

The desired end state code above illustrates the public interface of the KindBuilder class, using this information the following code snippet shows the Method Chaining public interface of KindBuilder:

    1: public class KindBuilder
    2: {
    3:     public KindBuilder IsNamed ( string name )
    4:     { }
    5:  
    6:     public KindBuilder CanBeDescribedAs ( string descriptiveInformation )
    7:     { }
    8:  
    9:     public KindBuilder CanBeIdentifiedByTheKeywords ( string keywords )
   10:     { }
   11:  
   12:     public KindBuilder IsStoredInFolder ( int folder )
   13:     { }
   14:  
   15:     public KindBuilder IsOwnedBy ( Party owner )
   16:     { }
   17: }

 

The code above is rather straightforward, with the only thing worthy of note is that each of KindBuilder’s public methods return back an instance of KindBuilder. As one might imagine, this is the “secret sauce” that allows Method Chaining to work.

However, the public interface of KindBuilder isn’t yet complete. While the code snippet immediately above addresses the Method Chaining aspect of KindBuilder’s public interface, line #1 of the desirable end state code snippet clearly illustrates that a KindBuilder instance gets converted to a Kind instance at the completion of the method chain. C#’s implicit operator makes this kind of goodness a snap to implement:

    1: public static implicit operator Kind ( KindBuilder builder )
    2: { }

 

The Complete KindBuilder

With the public interface of KindBuilder defined, all that is left is to add some simple state to the class and then implement the implicit operator. The following illustrates the complete KindBuilder class:

    1: public class KindBuilder
    2: {
    3:     private string Name { get; set; }
    4:     private string DescriptiveInformation { get; set; }
    5:     private string Keywords { get; set; }
    6:     private int Folder { get; set; }
    7:     private Party Owner { get; set; }
    8:  
    9:     public KindBuilder IsNamed ( string name )
   10:     {
   11:         Name = name;
   12:         
   13:         return this;
   14:     }
   15:  
   16:     public KindBuilder CanBeDescribedAs ( string descriptiveInformation )
   17:     {
   18:         DescriptiveInformation = descriptiveInformation;
   19:  
   20:         return this;
   21:     }
   22:  
   23:     public KindBuilder CanBeIdentifiedByTheKeywords ( string keywords )
   24:     {
   25:         Keywords = keywords;
   26:  
   27:         return this;
   28:     }
   29:  
   30:     public KindBuilder IsStoredInFolder ( int folder )
   31:     {
   32:         Folder = folder;
   33:  
   34:         return this;
   35:     }
   36:  
   37:     public KindBuilder IsOwnedBy ( Party owner )
   38:     {
   39:         Owner = owner;
   40:  
   41:         return this;
   42:     }
   43:  
   44:     public static implicit operator Kind ( KindBuilder builder )
   45:     {
   46:         return new Kind ( builder.Folder, builder.Name, builder.DescriptiveInformation, builder.Keywords, builder.Owner );
   47:     }
   48: }

 

For those that are interested, code for the SystemIdentityBase, Kind, and KindBuilder classes (with unit tests) is available for download from my SkyDrive. The link to the .ZIP is located a the bottom of this post.

 

Next Time

The subject of the next post will be coverage of the System.Identity Party class. As the models for System.Identity illustrate, Party is a central concept in System.Identity. Working the Party class using the architectural specifications for the fluent interface should be an interesting design exercise.

 

SkyDrive Files