April 2008 - Posts

Beginning with Singleton .Instance Peekaboo, and Ending Up with Why Singleton At All?

I know the title of this post is weird, but just bear with me a moment... 

Often time I found myself writing code like UserServices.Instance.DoSomething(...) when using Singleton pattern.  And afterward, I keep saying to myself, that's just ugly.  How can you rid yourself from the ugly .Instance. or .GetInstance(). or whatever that keep rearing its ugly head?  I want to be able to write UserServices.DoSomething(...) instead?

Looking at the desired syntax, one thing that keep popping into my mind is why don't you just change the class to a class with a bunch of static methods (utility class)?  That'll solve the problem right?

This led me around the web to find out the answer of why one should use Singleton instead of the utility class?  I came across this article.  But the argument there is quite weak in my opinion.  The author stated that "Utilities lead to a clear division between behavior and data that you should never allow in an object-oriented design." Well, yes, if it is purely a utility class, but there is no reason why can't you have static fields inside the class that you can still act upon through your static methods.  You can still maintain state that way and it still fullfills the primary purpose of a singleton which is to have only one "instance" of a particular class.  I also found this article (which provides a better argument, I think).  In the end of that one, someone eluded that perhaps Singleton is a "legacy" pattern from C++ time since nowaday Java and C# do have static initialization capability that you can depend on to put a class' static fields into certain states before you call any of its static methods.  Some other said that it's easier to maintain / reuse.  Frankly, at this time I have to admit that I don't have enough experience maintaining / reusing such singleton to see the real benefit of singleton over class with static methods.  Maybe some of you do, if so your input on this matter will be much appreciated.

I stumbled across a lot of discussions on this subject, which I won't bored you with.  If you wish to pursue the matter, google "singleton vs static", "polymorphic singleton".  You'll run into article ranging from why Singleton good and why Singleton is bad (i.e. this).

I even found myself perusing the HeadFirst Design Pattern book.  In the Singleton chapter, There are no dumb questions section, I finally found at least a reason that I can accept (still have to be experienced, however) of why you would use singleton instead of static methods (Quoted below).

Q: Can't I just create a class in which all methods and variables are defined as static? Wouldn't that be the same as a Singleton?
A: Yes, if your class is self-contained and doesn't depend on complex initialization.  However, because of the way static initializations are handled in Java, this can get very messy, especially if multiple classes are involved.  Often this scenario can result in subtle, hard to find bugs involving order of initialization.  Unless there is a compelling need to implement your "singleton" this way, it is far better to stay in the object world.

So, who am I to argue with people possesing more experience in this matter. Smile

So, let's go back to the initial problem.  How can you rid yourself from writing .Instance everytime you need to refer to your singleton object?  I guess you can cache the singleton once inside a class variable and use that instead.  Something like UserServices _userServices = UserServices.Instance;  and then just use _userServices.methodName(...) instead of calling UserServices.Instance.methodName(...).  If you don't like the different name, you can introduce something like UserServices UserServices = UserServices.Instance as your class variable.  Then you can call UserServices.methodName(...) from inside your class.

Another way to do this is a hybrid of the normal singleton and static methods, which is to hide the singleton Instance variable itself from getting exposed outside the class / its subclass and expose a bunch of static method that call the Instance.something like the example below:

 

   1:  public class UserMapper
   2:  {
   3:      protected static readonly UserMapper _instance = new UserMapper();
   4:      
   5:      protected UserMapper()
   6:      {
   7:        //Initialize stuffs here...
   8:      }
   9:      
  10:      private IUser doLoad(int id)
  11:      {
  12:        //Do the real loading of the data here...
  13:      }
  14:      
  15:      public static IUser Load(int id)
  16:      {
  17:        return _instance.doLoad(id);
  18:      }
  19:  }

 

Which way is better?  I'll leave it up to you...

Share this post: | | | |
Posted by Jimmy Chandra | 1 comment(s)
Filed under: ,

It's Time to Play SPOT THE BUG!!

*cheer*

All right, ladies and gentlemen.  I'm your host with the most, BuggyFixius.  *cheer and clappings*

Today we have an exciting web bug for you.  Let's see if you can... *altogether now* SPOT THE BUG!!

We have with us today, an ASP.NET website project *clappings*.  The project contain a helper class like so:

   1:  using System.Web;
   2:   
   3:  public class WebHelper
   4:  {
   5:      const string PARAM_USER_ID = "u";
   6:   
   7:      static HttpRequest request;
   8:   
   9:      static WebHelper()
  10:      {
  11:          request = HttpContext.Current.Request;
  12:      }
  13:   
  14:      public static string GetUserId()
  15:      {
  16:          return getRequest(PARAM_USER_ID);
  17:      }
  18:   
  19:      static string getRequest(string key)
  20:      {
  21:          string value = request[key];
  22:          return string.IsNullOrEmpty(value) ? string.Empty : value;
  23:      }
  24:  }

*Ooo, Aaaa and some gasps*

It also has a Default.aspx file containing a plain Label control

   1:  <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
   2:   
   3:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4:   
   5:  <html xmlns="http://www.w3.org/1999/xhtml" >
   6:  <head runat="server">
   7:      <title>Untitled Page</title>
   8:  </head>
   9:  <body>
  10:      <form id="form1" runat="server">
  11:      <div>
  12:          <asp:Label ID="Label1" runat="server" />
  13:      </div>
  14:      </form>
  15:  </body>
  16:  </html>

and the following Page Load event handler:

   1:  using System;
   2:  using System.Web.UI.WebControls;
   3:   
   4:  public partial class _Default : System.Web.UI.Page 
   5:  {
   6:      protected void Page_Load(object sender, EventArgs e)
   7:      {
   8:          Label1.Text = WebHelper.GetUserId();
   9:      }
  10:  }

*Some more Ooo, Aaaa and some more gasps*

Contestants... it's time to *altogether now* SPOT THE BUG!!

 Hints: open Default.aspx in the browser 2 or more times given a different u querystring.  For example: http://localhost:34939/Default.aspx?u=3959 and then replace the url with http://localhost:34939/Default.aspx?u=4000.

Share this post: | | | |
Posted by Jimmy Chandra | 5 comment(s)
Filed under: ,

On Activator.CreateInstance...

When you use .NET Activator.CreateInstance to create a new object of a certain type, make sure you reference the Project / DLL that contain the type definition or load it manually somehow to an AppDomain.  Otherwise your call will fail. Say you have the following solution:
Solution Foo
    Project Bar1
        IUser
        IDataMapper
          IUser Load(...);
    Project Bar2 (references Bar1)
        ADSpecificDataMapper : Bar1.IDataMapper
          IUser Load(...) { ... }
    Project Bar3
       User : IUser
          IDataMapper m_Mapper = Settings.Instance.UserMapper
          IUser Load(...) { return m_Mapper.Load(...) }
    Project Baz (references Bar1)
        Settings
           Settings Instance = new Settings() //singleton
           IDataMapper Mapper = CreateMapper(ConfigurationManager.AppSettings[...])
           IDataMapper CreateMapper(SpecificMapperClassNameFromAppConfig)
    Project ConsoleTester (references Baz, Bar3)
       Main
          IUser user = User.Load(...);
Note that ConsoleTester is not referencing Project Bar2 (which contain the ADSpecificDataMapper that will be created through the Factory Method CreateMapper in Baz.Settings class.  This will cause it to fail.  Adding Bar2 to the ConsoleTester project reference will remedy the probl
Share this post: | | | |
Posted by Jimmy Chandra | with no comments
Filed under: ,

How Do I Serialize / Deserialize Tidbits...

How do I serialize / deserialize between (XML Schema) XSD:Duration from and to .NET TimeSpan?

Apparently, there is no obvious way to do this like you could when dealing with DateTime object conversion to and from XSD:DateTime.  With DateTime you can do something like so:

   1:  //Serialize DateTime object to xsd:DateTime format
   2:  DateTime date1 = DateTime.Now;
   3:  string serializedDate1 = date1.ToString("yyyy-MM-ddTHH:mm:ssK");
   4:   
   5:  //Deserialize an xsd:DateTime format to a DateTime object
   6:  string serializedDate2 = "2008-04-14T21:00:00+07:00";
   7:  DateTime date2 = DateTime.Parse(serializedDate2);

But you cannot deserialize xsd:Duration to TimeSpan using TimeSpan.Parse and there is no obvious way to serialize the TimeSpan object also.

After digging around a little bit more, I encountered System.Runtime.Remoting.Metadata.W3cXsd2001 namespace.  What is this you might ask?  Well, it turned out that this is exactly the correct namespace to do Soap Serialization / Deserialization.  Just plop that namespace in the using section and you are ready to go.

The following code is the equivalent of the code above:

   1:  //Serialize DateTime object to xsd:DateTime format
   2:  DateTime date1 = DateTime.Now;
   3:  string serializedDate1 = SoapDateTime.ToString(date1);
   4:   
   5:  //Deserialize an xsd:DateTime to a Datetime object
   6:  string serializedDate2 = "2008-04-14T21:00:00+07:00";
   7:  DateTime date2 = SoapDateTime.Parse(serializedDate2);

And this is the code you need to serialize / deserialize TimeSpan object:

   1:  //Serialize TimeSpan object to xsd:Duration format
   2:  TimeSpan timeSpan1 = new TimeSpan(1, 0, 0);
   3:  string serializedTimeSpan1 = SoapDuration.ToString(timeSpan1);
   4:   
   5:  //Deserialize xsd:Duration to TimeSpan object
   6:  string serializedTimeSpan2 = "PT1H";
   7:  TimeSpan timeSpan2 = SoapDuration.Parse(serializedTimeSpan2);

To learn more about XML Schema go to http://www.w3schools.com/Schema/default.asp.

How do I serialize / deserialize object from and to JSON in .NET?

To do this, simply install ASP.NET AJAX extension on your machine.  You shouldn't need to if you have Visual Studio 2008 installed on your machine since it's already installed by default.  You will need to add the System.Web.Script.Serialization namespace to your using section.

Say you have a .NET User class like so:

   1:      public class User
   2:      {
   3:          public string Account { get; set; }
   4:          public string FullName { get; set; }
   5:      }

Serializing / Deserializing User object can be as simple as this:

   1:  string json = serializer.Serialize(new User { Account = "DOMAIN\\johndoe", FullName = "John Doe" });
   2:  User user = serializer.Deserialize<User>(json);

Apparently, .NET Framework 3.5 have some new stuffs up its sleeve like DataContractJsonSerializer that is supposed to replace the now obsolete JavascriptSerializer.

Share this post: | | | |
Posted by Jimmy Chandra | with no comments
Filed under: , ,