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.

Wednesday, 4 November 2009

System.Data.DataRow indexer complexity

Have you ever wonder what is the time complexity of accessing DataRow by column name? Unfortunately, this information is not specified on MSDN.

So the obvious answer would be O(n). We might think that there is iteration on data columns and in worst case it would iterate on all of them.

The actual answer can be discovered by looking on System.Data.dll using Reflector. We'll see there, that there is an access to Hashtable of column names by name, which obviosly take O(1).

So the overall complexity of the following would be O(1).

object data = row["CUSTOMER"];

Wednesday, 30 September 2009

How to retrieve new row data from INSERT using Oracle DataAccess

Answering a question on StackOverflow:

"I am using Oracle database server with Oracle DataAccess client. What I need to do is INSERT a new row of data, then retrieve the auto-generated ID field of the newly-created row for another INSERT command, immediately following. What is the best way to do this?"

Answer:
1. Modify the INSERT query by adding RETURNING keyword
"INSERT INTO table_name (column_name1, column_name2) VALUES ('val1', 'val2')
RETURNING module_id INTO :column_id"


* This source code was highlighted with Source Code Highlighter.

2. Add a bind variable to your OracleCommand named "column_id"
3. Take its value after the command is executed

Monday, 15 June 2009

V2: WCF CollectionDataContract and DataMember attributes

Following Jeff's comment on the first version of this post, here are some explanations and a full class.

Q1. Why did I write "implement IEnumerable" twice?
A1. My original intention was to derive my class from ICollection<T>. Thus I had to implement IEnumerable and IEnumerable<T>.

Q2. Why do I bother to implement IEnumerable at all if the class is not "decorated" as IEnumerable?
A2. ICollection<T> "derives" from IEnumerable<T> and IEnumerable, so we have to implement both of them when writing a class that implements ICollection<T>

Here is a complete class:

 [DataContract]
  public class EntityCollectionWorkaround<EntityType> : ICollection<EntityType>
  {
    #region Constructor
    public EntityCollectionWorkaround()
    {
      Entities = new List<EntityType>();
    }
    #endregion

    [DataMember]
    public int AdditionalProperty { get; set; }

    [DataMember]
    public List<EntityType> Entities { get; set; }

    #region ICollection<T> Members

    public void Add(EntityType item)
    {
      Entities.Add(item);
    }

    public void Clear()
    {
      this.Entities.Clear();
    }

    public bool Contains(EntityType item)
    {
      return Entities.Contains(item);
    }

    public void CopyTo(EntityType[] array, int arrayIndex)
    {
      this.Entities.CopyTo(array, arrayIndex);
    }

    public int Count
    {
      get
      {
        return this.Entities.Count;
      }
    }

    public bool IsReadOnly
    {
      get
      {
        return false;
      }
    }

    public bool Remove(EntityType item)
    {
      return this.Entities.Remove(item);
    }

    public EntityType this[int index]
    {
      get
      {
        return this.Entities[index];
      }
      set
      {
        this.Entities[index] = value;
      }
    }
    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<EntityType> GetEnumerator()
    {
      return this.Entities.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
      return this.Entities.GetEnumerator();
    }

    #endregion
  }


* This source code was highlighted with Source Code Highlighter.

Monday, 8 June 2009

Post-build assembly manipulation

We often think how to modify our code during writing, debugging, but rarely after assembly is built. Well, there are a few kinds of post-build manipulations we might want to perform on compiled assemblies:

Merge
This nice utility was developed by Mike Barnett from Microsoft Research and it enables merging multiple assemblies to a single one. This may be very useful, when one wants to deliver a single component or executable without exposing the internal structure of assemblies. It may be used as command-line utility (from post build action as well) and as a assembly reference and wrapped within another tool. It does not work on Silverlight assemblies, at least at the moment of writing these lines and I asked Mike to check this out.
http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx

Convert to Silverlight
This project developed by Suriel Bendahan enables converting assemblies compiled on server-side .NET to Silverlight compatible assemblies. It makes possible to reuse code written as "server-side" on Silverlight client. It might be useful for generic data structures, generic algorithms, input validations, sharing interfaces etc. The project is provided with it sources, so it can be modified/adopted for your needs.
http://www.codeproject.com/KB/silverlight/SLAssemblies.aspx

Compress
Silverlight assemblies are being downloaded to browser in a XAP file, which is a bunch of DLLs compressed using ZIP compression. This project developed by Rob Houweling uncompresses these assemblies and compresses them again with a higher compression rate. This is very useful when XAP size becomes an issue.
http://web-snippets.blogspot.com/2008/11/another-one-on-repacking-xaps-to-reduce.html

Obfuscate
Obfuscation is a process of changing the readability of the code without changing its functionality. The reason for doing this is preventing others from seeing implementation. Visual Studio comes with a Dotfuscator Community Edition and there are others providers of obfuscation utilities.