Monday, August 27, 2007

Multi-value Flag Pattern (a.k.a. specialized enumerations)









Multi-value Flag
Pattern (a.k.a. specialized enumerations)











In software development, a flag is a mark placed on an
object instance or data record in order to signal a particular status or
condition or to keep a record on whether a particular event has occurred
concerning the specified data. Mostly flags are binary, meaning they represent
a Boolean value; they are either true or false. We see many binary flags
represented as Boolean typed properties or bit typed data fields and they
include cases like marking an object as “Active”, “Obsolete”, “Recorded”, among
others.



Sometimes it is necessary for a flag to be able to get more
than the two binary values “true” and “false”. In these cases, enumerations
come handy as they provide a very simple way to declare, use and store several
values without having to deal with error prone value types while at the same
time being able to store easy to convert values in the data repository. So by
using enumerations you can relate “Inserted” with 0, “Reviewed” with 1,
“Approved” with 2, “Published” with 3, and finally “Edited” with 4. With this
relationships you are able to flag your object as “inserted” in the system,
later after someone has gone through the contents making sure everything is OK
you can change its value to “Reviewed”; after the revision is done content
needs to be “approved” by a third actor and finally all approved contents are
“published” to the UI. Days later the content is “edited” again and it needs to
go through the process again.



There are however, very specific cases when representing
flag values with integers do not meet the requirements, as maybe you need the
raw data returned by a query to the database to be understood at first sight or
to be provided or used by third parties while at the same time you have to
consider storage limitations and using lengthy flag values might be
unreasonable. The easier way to solve this problem would be to use a single
character for the flag values, as they are easy to remember and take only a
byte for each record. Using this technique we can represent the values
mentioned before by storing “I” for “Inserted”, “R” for “Reviewed”, “A” for
“Approved”, “P” for “Published” and “E” for “Edited”. But as we cannot assign
String values to enumerations we lose the convenience of strong-typing and
might get trapped in error prone practices like leaving the value that is
stored open to the developers, who might unknowingly type wrong values in
certain portions of code. In order to be able to use this kind of values in the
data repository we need to create a way to solve the following problems:



1. Being
able to use strong typed values during development.



2. Being
able to avoid hard-to-maintain conversion techniques between strong typed
values and value types.



3. Being
able to still pass value types to the Data Abstraction Layer without having to
resort to case-by-case conversion techniques.



4. Ensuring
developers won’t be able to mistakenly pass inexistent values to the flag.



5. Begin
able to store non-numeric values in the database.



In order to achieve this behavior we need to “emulate” the
behavior of an enumeration, making sure we can associate non-numeric values to
the flag.



Let’s start by declaring the type we will use for our
specialized enumeration:





public sealed class ProductStatus {





#region Properties





/// <summary>



/// Value that will be represent this status in the data
repository.



/// </summary>



public String StoringValue {



get { return storingValue; }



}



private String storingValue;





/// <summary>



/// Value that will represent this status in the UI.



/// </summary>



public String DisplayValue {



get { return displayValue; }



}



private String displayValue;





#endregion





#region Constructor





/// <summary>



/// Initializes a new instance of the ProductStatus flag.



/// </summary>



/// <param
name="storingValue">
Value that
will represent this status in the data repository.
</param>



/// <param
name="displayValue">
Value that
will represent this status in the UI.
</param>



/// <remarks>



/// The constructor of the class is marked as private in order
to prevent external users from



/// being able to create new instances of the ProductStatus.



/// The multi-value flag pattern represents an extension of
the singleton pattern in which



/// instead of just one, a limited series of instances of the
class are allowed to exist.



/// </remarks>



private
ProductStatus(String storingValue, String displayValue) {



this.storingValue
= storingValue;



this.displayValue
= displayValue;



}





#endregion





}







The class is marked as “sealed” as the first barrier for preventing
developers from being able to assign incorrect values to the flag. If it is
possible to inherit from our class it would be possible to generate more
instances of the ProductStatus type leading to an incorrect assignment. The
class also declares a unique private constructor and two properties. The properties
will store the values that will be used to represent the status in the data
repository and the user interface. The constructor is marked as private in
order to control how many instances of the class are created at any given time.



Now that we have the reference type that will represent our
flag, we need to create its instances. In order to do that we will add the
following static properties to the class:







#region Static Properties





/// <summary>



/// Represents the pending status of a product.



/// </summary>



public static readonly ProductStatus Pending = new
ProductStatus("P",
"Pending");





/// <summary>



/// Represents the approved status of a product.



/// </summary>



public static readonly ProductStatus Approved = new
ProductStatus("A",
"Approved");





/// <summary>



/// Represents the published status of a product.



/// </summary>



public static readonly ProductStatus Published = new
ProductStatus("B",
"Published");





#endregion









Now we can easily reference each instance the same way we do
with enumerations, using the “Type.Instance” formula:





product.Status = ProductStatus.Approved;







In order to make sure the properties declared with this type
on the business object are going to be compatible with the model we’re using
where the BAL and the DAL are loosely-coupled, it is necessary to ensure our
instance will implicitly be converted to String, just like enumerations are
seamlessly converted to Int32 values. We achieve this by declaring implicit
operators on the class:







#region Operators





/// <summary>



/// Implicitly converts the status value into the storing type
in order to



/// achieve transparent communication between loosely coupled
layers.



/// </summary>



/// <param
name="value">
Status value to be
converted.
</param>



/// <returns>Resulting status value.</returns>



public static implicit operator String(ProductStatus value) {



return
value.StoringValue;



}





/// <summary>



/// Implicitly converts storing type (String) values into
(allowed) product



/// status values so that they can be retrieved from the
database without



/// the need for explicit conversion. This eliminates the need
for the data



/// abstraction layer to know about the status pattern
implementation.



/// </summary>



/// <param
name="value">
String value to
convert.
</param>



/// <returns>The status value that corresponds to this string.</returns>



public static implicit operator ProductStatus(String value) {



return ProductStatus.GetProductStatus(value);



}





#endregion









The implicit operator uses the following methods to obtain
its value:







/// <summary>



/// Gets the collection of allowed values of this class.



/// </summary>



/// <returns></returns>



public static IEnumerable<ProductStatus> GetAllowedValues() {



yield return ProductStatus.Pending;



yield return ProductStatus.Approved;



yield return ProductStatus.Published;



}





/// <summary>



/// Searches inside the list of allowed values for one where



/// the storing value equals the proportioned string. If the
value



/// is not found null is returned.



/// </summary>



/// <param
name="value">
String to look for
in the list of allowed values.
</param>



/// <returns>The ProductStatus value corresponding to the specified
string or null if the value is not found.
</returns>



public static ProductStatus
GetProductStatus(String storingValue) {



foreach
(ProductStatus status in ProductStatus.GetAllowedValues())
{



if
(status.StoringValue == storingValue) {



return
status;



}



}



return null;



}









Finally in order to complete the implementation we add
utility methods and override the ToString() method of the Object class to make
sure the correct values are printed on the UI without having to invest any additional
code in the presentation layer:







/// <summary>



/// Gets the storing value that corresponds to the specified
display value.



/// </summary>



/// <param
name="value">
Display value to
find.
</param>



/// <returns>A string that represents the storing value corresponding to
the specified display value or null.
</returns>



public static String
GetStoringValue(String displayValue) {



foreach
(ProductStatus status in ProductStatus.GetAllowedValues())
{



if
(status.DisplayValue == displayValue) {



return
status.StoringValue;



}



}



return null;



}





/// <summary>



/// Gets the display value that corresponds to the specified
storing value.



/// </summary>



/// <param
name="value">
Storing value to
find.
</param>



/// <returns>A string that represents the display value corresponding to
the specified storing value or null.
</returns>



public static String
GetDisplayValue(String storingValue) {



foreach
(ProductStatus status in ProductStatus.GetAllowedValues())
{



if
(status.StoringValue == storingValue) {



return
status.DisplayValue;



}



}



return null;



}





/// <summary>



/// Returns the UI-compatible representation of the status.



/// </summary>



/// <returns></returns>



public override string
ToString() {



return this.DisplayValue;



}









If in the future it is necessary to add new status values to
the class it would be necessary to add two lines of code to the implementation:





public static readonly ProductStatus NewStatus = new
ProductStatus("N",
"NewStatus");





Declaring the static property.





public static IEnumerable<ProductStatus> GetAllowedValues() {



yield return ProductStatus.Pending;



yield return ProductStatus.Approved;



yield return ProductStatus.Published;





yield return ProductStatus.NewStatus;





}





Adding the additional return value to the GetAllowedValues()
method.



You can download the complete implementation and a very
simple use case in a WinForms UI here.



Monday, July 16, 2007

Silverlight 1.0: Preparing for the release candidate

Tim Sneath has announced on his blog that the first release candidate for Silverlight 1.0 will be made public in a couple of weeks. It is important for people with current and upcoming developments using Silverlight to prepare for this release as two very important things will happen:
  • Some of the changes on this release will break previous Silverlight applications
  • From this release and on and until the final release of the product no more breaking changes will be introduced.

So if you and your team have projects in Silverlight and you want to keep them up to date and running on this release you should be preparing for the breaking changes, as listed in Joe Stegman's recent blog entry.

At this point you can prepare by downloading a specific SDK for this version that will also include a document listing these changes and will teach you how to detect whether the application is running on the beta or RC version of the plug-in in order to make it compatible with both of them.

You can download this "Preview SDK" here.

Note: this file does not contain the release candidate, instead it contains the necessary information for you to start preparing for this release.

Currently there is no official date for another release of Silverlight 1.1. The Alpha version released in May is the most recent one and the Silverlight team has currently no plan for releasing a new version in the immediate future, despite a strong preference in the community about the 1.1's .NET version of Silverlight compared to 1.0's JavaScript support.

Thursday, July 12, 2007

Images from LiveSpace into PhotoSphere


I signed up for Microsoft's Popfly sometime ago, but haven't really had time to get deeper into it.

Today I started playing with it and created my first "mashup": Images from LiveSpace into PhotoSphere.

A mashup is basically a combination of plug-ins that interact between them using a certain protocol. Some plug-in server data, others use this data and present it in a certain way.

For this specific mashup I'm using a plug-in that will output image links from my LiveSpace account. Those links will serve as input for another plug-in that will present the images in a SilverLight interface with a really cool rotating effect around a 3D Sphere.

You can see the result above these blog entry.

Note: You'll need the SilverLight plug-in and it takes some time to download all the images before you see anything.

Saturday, May 12, 2007

Using C# 3.0's Extension Methods to generate MCML from Reference types

Other versions of the article:

HTM Version

XPS Version

C# 3.0 features Extension Methods, static methods which will let you extend the functionality of
existing types, without having to sub-class the type or modifying the original source code. This article discusses how to use this feature to generate Media Center Markup Language (MCML) in a re-usable and extensible way.


The basics: Value Types


Let’s start by creating a very basic extension method:


public static String ToMcml(this string target, string name) {

return String.Format("<cor:String Name=\"{0}\" String=\"{1}\"/>",

name, target);

}


Notice the keyword “this” in front of type “string” which let’s the compiler know which type is going to be extended by this method. In this case adding a reference to the namespace where this method is implemented will add the “ToMcml” method to any instance of type string.


This lets the developer generate the MCML markup for any string in the following forms:



String mcmlText = String.Empty;

Console.WriteLine(mcmlText.ToMcml("McmlProperty"));

Console.WriteLine("String
Value"
.ToMcml("AnotherMcmlProperty");


After this is ready, adding overloads for additional value types is a pretty straight-forward process.


Converting Reference Types to Property Sets


Converting Reference Types is not as easy and will require some additional code and the use of Reflection. If we want these extension methods to be really reusable we want them to be able to act over any type and not just a specific one. This means we have to resort to extending type “object”, base of any other type in the framework, and re-use any other extension method we had already implemented to convert value types, in the following way:



public static String ToPropertySet(this object target, String name) {

String result = String.Empty;

Type type = target.GetType();

result += String.Format("\n <!-- Main Type Name: {0} -->",
type.Name);

PropertyInfo[] propertyInfoArray = type.GetProperties();

result += String.Format("\n <!-- Field count: {0} -->",

propertyInfoArray.Length);

foreach (PropertyInfo propertyInfo in propertyInfoArray) {

result +=

String.Format("\n <!-- {0} -->",

propertyInfo.PropertyType.Name);

switch (propertyInfo.PropertyType.Name){

case "String":

result += "\n " +

((String)propertyInfo.GetValue(target,null))

.ToMcml(propertyInfo.Name);

break;

}

}

result = String.Format("\n<Entries>{0}\n</Entries>",
result);

if (name != null) {

return result = String.Format(

"<PropertySet Name=\"{1}\">{0}\n</PropertySet>",

result,

name);

} else {

return result = String.Format(

"<PropertySet>{0}\n</PropertySet>",

result);

}

}

Although up to this point this method will only convert properties of String type, it is not a problem to add additional conversions methods and cases for value types.


It is also possible to change the “String.Format” method calls by proper XML handling techniques; however this is beyond the purposes of this article.


The result: MCML


Once we have a reference to the namespace where these methods are implemented, we can apply them the following way:


Declaring a new reference type (the C# 3.0 way):



public class TestType {

public string Name { get; set; }

public string ID { get; set; }

public string VideoUri { get; set; }

}


Instantiating, initializing and calling the extension method:


TestType target = new TestType();

string name = "TestPropertySetName";

target.ID = "{5B1BFC9A-9BFE-42f8-9655-B736496CAA4B}";

target.Name = "TestName";

target.VideoUri = "http://www.test.com/";

Console.WriteLine(target.ToPropertySet(name));


Following the output in the console:


<PropertySet Name="TestPropertySetName">

<Entries>

<!-- Main Type Name: TestType -->

<!-- Field count: 3 -->

<!-- String -->

<cor:String Name="Name" String="TestName"/>

<!-- String -->

<cor:String Name="ID" String="{5B1BFC9A-9BFE-42f8-9655-B736496CAA4B}"/>

<!-- String -->

<cor:String Name="VideoUri" String="http://www.test.com/"/>

</Entries>

</PropertySet>


This is a definitely useful technique for web-hosted MCML applications which backend is implemented using version 3.5 of the .NET Framework. Although this is not likely to happen any time soon, I sincerely cannot wait for it J