Thursday 22 July 2010

Microsoft AppFabric (former Velocity code name)

I visited yesterday a "Introduction to AppFabric caching" session in Microsoft offices in Raanana. The session was held by AppFabric team developer - Shani Pozin. In this post I'd like to summarize the session for those who missed it and as a reminder for myself.

What is AppFabric Caching?

1. A successor of Velocity - a distributed cache service
2. A part of AppFabric - Microsoft vision of application server
3. A competitor to Memcached, NCache and others

What does it do?

It provides an abstract level of clustered distributed caching for serializable objects. Cached data is stored in different physical machines in order to enable High Availability. Each value is stored in two machines (if configured) Primary and Secondary. If Primary fails, then Secondary becomes Primary and another machine becomes Secondary. If Secondary fails, another machine is chosen to be secondary.

What are additional things it knows to do?

1. There is support for locking objects they are retrieved from cache. It is provided by GetAndLock and PutAndUnlock methods. It is important to mention, that if object is locked by one thread the other one will receive an exception and will not be blocked.
2. There is support for versioning cached objects. If a thread is trying to Put an older version of cached object, it will experience an exception, saying that it has to get the most updated version from cache.

What it does not do?

1. It does not persist cached data, which is different than Velocity worked. There were several options for data persistency: SQL Server, XML file, MDF file.
3. It does not provide Read-through and Write-behind features. It is promised, that they will be supported in future releases

If/when the presentation will be available on the web, I'll put a link here.

Wednesday 23 June 2010

Get browser information from Silverlight

Recently I needed to detect information about browser version within Silverlight. After googling around I found many posts that pointed to built-in class BrowserInformation, which can be accessed via System.Windows.Browser.HtmlPage.BrowserInformation.

So I should be happy and use its Name and BrowserVersion properties?

No, because BrowserVersion property returns something similar to HTML version instead of the real browser version. For example, on "Internet Explorer 7.0", it returns "4.0"

The "real" browser version can be extracted from the mysterious UserAgent property, just like this:

public static string BrowserName()
{
  string userAgent = HtmlPage.BrowserInformation.UserAgent;
  if (userAgent.IndexOf("MSIE 8.0") > 0)
  {
    return "Internet Explorer 8.0";
  }
  if (userAgent.IndexOf("MSIE 7.0") > 0)
  {
    return "Internet Explorer 7.0";
  }
  if (userAgent.IndexOf("MSIE 6.0") > 0)
  {
    return "Internet Explorer 6.0";
  }
  if (userAgent.IndexOf("MSIE 5.0") > 0)
  {
    return "Internet Explorer 5.0";
  }
  if (userAgent.IndexOf("Firefox") > 0)
  {
    return "Mozilla " + userAgent.Substring(userAgent.IndexOf("Firefox"), 100).Replace('/', ' ');
  }
  if (userAgent.IndexOf("Chrome") > 0)
  {
    return "Google " + userAgent.Substring(userAgent.IndexOf("Chrome"), userAgent.IndexOf("Safari") - userAgent.IndexOf("Chrome")).Replace('/', ' ');
  }
  if (userAgent.IndexOf("Safari") > 0)
  {
    return "Safari " + userAgent.Substring(userAgent.IndexOf("Version"), userAgent.IndexOf("Safari") - userAgent.IndexOf("Version")).Replace("Version/", String.Empty);
  }
  if (userAgent.IndexOf("Opera") > 0)
  {
    return userAgent.Substring(userAgent.IndexOf("Opera"), userAgent.IndexOf("(") - 2).Replace('/', ' ');
  }
  return "Unknown Browser";
}


* This source code was highlighted with Source Code Highlighter.

The code was successfully tested on IE and Chrome.

Thursday 4 March 2010

Upgrade to Visual Studio 2010 Release Candidate

After using VS2010 Beta for a while, I upgraded it to RC recently. It seems to be more stable and robust. So here are steps for upgrade:

1. Uninstall VS 2010 Beta
2. Install VS 2010 RC
3. Run VS2010 RC setup again and choose Repair
4. Download and install Hotfix KB980610

UPDATE March 7, 2010:
5. Download and install Hotfix KB980920

Deep cloning object in C#/.NET

I was asked recently to write a generic method for deep cloning of a complex object. The object contains references to other objects, collections, which contain references to many other objects and collections. The method was supposed to work on both platforms: .NET 3.5 (or higher) and Silverlight.

While googling I found a good post listing different approaches for cloning
C# Object Clone Wars

Last technique described in that blog points to Copyable Framework - generic framework for copying/cloning any objects using method extensions

The framework, written by Håvard Stranden addresses most of my requirements, except one: it does not work on Silverlight.

I came up with a simple method that serializes the original object and deserializes it to a cloned copy of it. It can be used as an extension or by implementing IClonable interface:

public static class ObjectExtensions
{
  public static T Clone<T>(this object original)
  {
    T cloned;
    using (MemoryStream stream = new MemoryStream())
    {
      DataContractSerializer serializer = new DataContractSerializer(typeof(T));
      serializer.WriteObject(stream, original);
      stream.Position = 0;
      cloned = (T)serializer.ReadObject(stream);
    }
    return cloned;
  }
}


* This source code was highlighted with Source Code Highlighter.

Tuesday 9 February 2010

WCF Serialization Tips

Here are a few tips on how to improve WCF performance and traffic by simple putting the right attributes on your serializable classes:


1. "Avoid inferred data contracts (POCO). Always be explicit and apply the DataContract attribute" (C) Juval Löwy
2. "Use the DataMember attribute only on properties or read-only public members" (C) Juval Löwy
3. Mark [DataMember] only properties, that DO have to be serialized. Avoid marking calculated properties as DataMember
2. Consider using (IsReference = true) on classes to avoid data duplication and circular references.
3. Use short (one or two letters) Name on classes and properties to significantly reduce traffic. (C) Eyal Vardi
4. Specify short Value for EnumMember
5. Use parametrized DataContract property for generic classes
6. Use (EmitDefaultValue=false) on properties to reduce traffic

Sample:

[DataContract(Name="CT")]
  public enum CustomerTypes
  {
    [EnumMember(Value = "I")]
    Internal,
    [EnumMember(Value = "E")]
    External,
    [EnumMember(Value = "U")]
    Unknown
  }

  [DataContract(IsReference = true, Name = "B{0}")]
  public class BusinessBase<T>
  {
    T Id { get; set; }
  }

  [DataContract(IsReference = true, Name = "C")]
  public class Customer : BusinessBase<int>
  {
    [DataMember(Name="C", EmitDefaultValue=false)]
    public CustomerTypes CustomerType { get; set; }

    [DataMember(Name = "N", EmitDefaultValue = false)]
    public string Name { get; set; }

    [DataMember(Name = "P", EmitDefaultValue = false)]
    public Customer ParentCustomer { get; set; }

    public bool IsGoodCustomer
    {
      get
      {
        return this.CustomerType == CustomerTypes.Internal || this.CustomerType == CustomerTypes.External;
      }
    }

  }


* This source code was highlighted with Source Code Highlighter.