Monday, February 28, 2011

In a hotel with infinite occupied rooms : Hilbert's paradox of the Grand Hotel

While watching BBC Horizon : To Infinity and Beyond a question is mentioned:
In a hotel with infinite rooms all of which are occupied. Can you accomodate a newly arriving guest?

The answer is yes. Since you can move guest in room 1 to room 2, Previous guest in room 2 to room 3, room 3 guest to room 4 and so on ... Ad infinitum.

What the episode on youtube. It is fun. 

I would assume that this would be fairly apparent to math majors:
http://en.wikipedia.org/wiki/Hilbert's_paradox_of_the_Grand_Hotel

But nonetheless was new to me and and answer is easily discoverable if you have a firm grasp of infinity.

Sunday, February 27, 2011

.NET Nugget : Viewing the serialized output of a DataContract on the console

Here are the steps (call it denotes sample variable names):
  • Create a DataContractSerializer of the type of the DataContract class (call it dcs)
  • Create a StringBuilder (call it sb)
  • Create an XmlWriter from the string builder ( call it writer)
  • use the dataContractSerializer.WriteObject to write the item instance to the xmlwriter. 
  • Print the sb.ToString to the console.

Heres the code: 

DataContractSerialzer dcs = new DataContractSerialzer(typeof(DataContractClass));
StringBuilder sb = new StringBuilder();
using(XmlWriter writer = new XmlWriter(sb))
{
   dcs.WriteObject(writer,dataContractClassInstance);
}
Console.WriteLine(sb.ToString());
Enjoy!

Saturday, February 26, 2011

Cmd Error: unc paths are not supported : Resolution.

Scenario:
I have a console application that runs on a network share. It does not function on the share but functions fine on my local vista machine. It is a dot net application that provides the details of the exception on the command line. Now I cannot run it on the lan from cmd (command prompt) because cmd exits with the error "unc paths are not supported".

Fortunately, cmd can be made to run on lan shares.
http://support.microsoft.com/kb/156276

Pretty simple really. Just create a REG_DWORD named DisableUNCCheck  with value 0x01 under:
HKEY_CURRENT_USER\Software\Microsoft\Command Processor

no need to restart explorer or anything. Just start cmd using a bat file in the desired network share and run the console application to view the output. 

Friday, February 25, 2011

A gem on DSL syntax from the book : DSLs in Boo: Domain-Specific Languages in .NET

The reason why I fell in love with programming in the first place was the sheer quality of the information available. Compare this to say Telecom engineering where high quality material is few and hard to find. This book is just another fine example of the quality of content created for programmers.

Here are just some of the things relevant to DSL programming in general that I found intriguing in just a few pages of the book:

Gems on the syntax of the DSL: 
It is going to be an iterative process. There are no two ways about it. But like all things programming there are good and sloppy ways of going about it.

1.) A good way to come up with the syntax is to start with pretending your DSL is in plain English and write it down. e.g.
If Book Is Available then Buy it.

The syntax should cover a single scenario. You cannot imagine all the scenarios into a single syntax sample. 

2.)Now simplify the syntax sample, indenting it and breaking it into lines.g.:
if Book Is Available
    then buy book

3.)Then use your possible syntax toolbelt (that is things that are easily expressible in internal DSLs) to arrive at the final result e.g.:
if Book.IsAvailable:
    Buy

Try another scenario, iterate.
Also it is a good idea not to let the technical implementation details leak into the DSL syntax.
Also, I could have said Buy Book but rather since we check Book to be available it is clear (and less technical noisy) if we just say Buy.

There is soooo much more information packed in the book.
Disclaimer: This post is based on my understanding of the content in the book.


Thursday, February 24, 2011

Book Review: DSLs in Boo: Domain-Specific Languages in .NET

In short : Buy it. This book (DSLs in Boo: Domain Specific Languages in .NET) is the best book on DSL programming that you will ever read ... and really you should read a book on DSL programming. Even if you never do it. You never know when you might need it.

This book is written by one of the smartest programmers alive. The book uses Boo as the programming language of choice for DSL. The reasons for this are mentioned in chapter two of the book under "Boo’s built-in language-oriented features" Highly convincing. And he even mentions why its a better idea than IronPython and IronRuby. Boo is a respected language and you have admit that "wrist friendly language for the CLI" is pretty catchy. Also I recommend you get sharpdevelop (now at version 4!) to play a little with Boo.

The book is as complete a DSL book as you can get. I am still going through the book and am 4 chapters in (along with reading 4 other books... one of them being for my upcomming ADO.NET 4 certification exam ... all great books ... I really should review books more often). Also it is the only book on Boo that I know of.

PS: Boo just released a .NET framework 4 version of the binaries which means that you can use it freely in your latest and greatest cutting edge applications. 

Wednesday, February 23, 2011

Sessions I am keeping a keen eye out for in MIX 2011

http://live.visitmix.com/OpenCall

These are sessions I can hardly wait to see:

Deep Dive MVVM
Effective Validation Techniques with MVVM in Silverlight
Facebook Development in .NET
Designing Infographics for Web Applications
(If just for the eyecandy!)


I am sure that all the session are going to be awesome. But these are the ones I am really excited about.  

Introduction to Algorithms Lecture 2

Available on youtube at:

http://www.youtube.com/user/basaratali?feature=mhum#p/a/A7062CB4B95A85BA/1/whjt_N9uYFI

Here is what is covered in it:

  • The bit O notation 
    • Yes he is correct in the beginning when he writes 2n^2 = O(n^3) . It is because the notation itself is open for the function (2n^2) being < and =  to O but we like to keep the O result (being engineers) to be as close to the original function as possible. Actually we are using the Theta notation which is a valid O as well.  
  • The Omega notation 
  • The Theta notation 
    • Engineering definition covered in lecture one : drop the leading constant and lower order terms :)
  • The small O and small Omega notation. The difference from their big brothers is that these are for < and > rather than <= and >= 
And then the cool stuff 
  • Asymptotic analysis of recursive algorithms. The algorithm complexity is known and defined as T(n) (call this expression 1).
    Methods:
    • Using substitution method. It uses mathematical induction by saying if big O for T(k) is (put an assumed/guessed expression in terms of k ... call this expression 2) complexity for n should be T(n) <  (put n in expression 2). The induction is carried out by putting T(n) from expression 2 into expression 1 and verifying the "should be" clause. If you find this tricky the lecture is awesome for explaining this. 
    • Using a recursion tree. The instructor's favorite method. You need to draw it to explain it so watch the video :) It was also used in lecture one for merge sort. 
    • Using the master method : The recursion algorithm must be of equal sized sub problems. e.g. in merge sort we divide the original problem into two equal sized (two equal sized means halved) sub problems. It will not work on e.g. T(n) = T(n/2) + T(n/3) etc. You can do non recursive work (denoted by f(n) ). So in short the limitation is that T(n) must be of the form aT(n/b) + f(n).
      The actual method are three cases (where you do a substiution in T(n) expression 1 and observe the result) that need to be remembered and it will immediately give you the running time.
      The lecture also presents an intuitive derivation of why the master method works (COOL). The guy that pointed out the height of the recursion tree to be "log (base b) of n" beat me to it. I felt a bit hurt that it didn't come to me immediately (sad pause). This image explains it:
Enjoy!

Tuesday, February 22, 2011

Going through MIT open courseware for Introduction to Algorithms

The complete class is available online. I am making a playlist of it as I go through it:
http://www.youtube.com/user/basaratali?feature=mhum#p/c/A7062CB4B95A85BA

Awesome stuff.
Here's what is covered in Lecture One:

  • Insert Sort
  • Merge Sort
  • Theta notation demonstrated for these two sorts
  • Cool: How to determine the complexity ( asymptotic analysis for runtime ) for an algorithm that uses recursion (in this case merge sort) 
Check it out: 

After the lecture you can enjoy this comic:
http://www.smbc-comics.com/index.php?db=comics&id=1989
haha merge sort for 5 items .....

Monday, February 21, 2011

LINQ : Whats the purpose of AsEnumerable?

AsEnumerable has a funny method signature:


public static IEnumerable AsEnumerable(
 this IEnumerable source
)

But there is a good reason for this function to exist. The reason is that your collection might not be acually an IEnumerable and infact inherit from IEnumerable. In that case any extension methods (e.g. Where ) overridden in the class that inherits from IEnumerable will get called. Sometimes you just want to call the extension method as implemented for IEnumerable (i.e. LINQ to objects). In this case you can use the AsEnumerable extension method and then call the extension method and linq to objects kicks in instead of Linq2SQL / Linq2Entities etc. 




Sunday, February 20, 2011

.NET cool things

Some things I think everyone in .NET should know :)

Enjoy!

Saturday, February 19, 2011

LINQ syntax for left outer join

Hint : Use the DefaultIfEmpty() extension and the into contextual keyword

The trick is to store the result of the join into a collection and the select from the outer collection and the into 

e.g.:

var expr = from p in products 
               join o in customersOrders  
                    on p.IdProduct equals o.IdProduct
                    into orders
               
                    from order in orders.DefaultOrEmpty()
                         select new
                         {
                            p.IdProduct, 
                            Name = o.Name               
                         }


Notice that the only thing that makes it a left outer join is the use of into orders and then from using the orders.DefaultOrEmpty.

Ofcourse a right outer join is a left outer join with the collection orders swapped. 


Enjoy!

Friday, February 18, 2011

LINQ to objects : The impact of join order

Here's the sample syntax of the join clause:

var expr = from a in collectionA
           join b in collectionB
                on a.AKey equals b.BKey
           ...


Notes:

  • equals is a contextual keyword specifically for LINQ. 
  • In the on section the first rangeItem (a) Must come before the second rangeItem (b) . Otherwise the query will not compile. 
  • Internally for LINQ to objects the first collection is looped storing the hash for each Key. And then the second item is looped computing the hash and comparing it to the first item. So the output will contain order of the items in the first collection :)

Enjoy!



Thursday, February 17, 2011

LINQ : Notes about sorting

The Ascending Keyword:
The default order for the orderby keyword is ascending. So in actuality specifing ascending in a LINQ query is only there for explicit mentioning for the ease of the programmer and is ignored by the compiler.

In fact orderby translates into one of four possible extension methods by the compiler:


A bit more:
http://dotnetperls.com/ascending

The return type is IOrderedEnumerable
IOrderedEnumerable inherits from IEnumerable and the reason it exits is because of ThenBy and ThenByDescending . These extension method only function on IOrderedEnumberable.

These are called when you politely write such linq queries:

var expr = from c in customers 
                      orderby c.Name descending, c.City
                                   select new { c.Name, c.City };



the c.City sorting is actually added using ThenBy.

Also bet you didn't know Reverse
Although it has no corresponding LINQ query syntax and you need to use the Extension method. It simply reorders the first item to be last etc.

What is the algorithm used by LINQ for sorting?
LINQ to objects uses quicksort. You can verify this by opening up System.Linq.EnumerableSorter in reflector.
For any other implementation of LINQ it is up to the implementation (ofcourse) e.g LINQ2SQL it will get traslated to SQL order by and it will be up to SQL Server to carry out the sorting and pick a sorting algorithm.



Wednesday, February 16, 2011

LINQ Tutorial : SelectMany extension method

Here's another thing I did not know about LINQ that I found out from this book.
SelectMany is how LINQ internally translates a collection of a collection into a flat collection.

Say you have a class:

public class Customer
{
      public Order[] Orders;
} 


and you write the following LINQ:


var orders = from customer in Customers
             select customer.Orders;


Needless to say you get an IEnumerable<order[]>
However if you want an IEnumerable<order> you can do that in LINQ syntax simply as:

var orders = from customer in Customers
                  from order in customer.Orders
                       select order;



The compiler will actually translate it into a SelectMany call :
var orders = Customers.SelectMany(customer => customer.Orders);


Note:
In fact SelectMany will always be called when there is a from after the first from.



Tuesday, February 15, 2011

About LINQ : Degenerate Queries

Degeneration is a law of nature. No seriously. But that's not what we are talking about here. We are talking about degenerate queries.

Here is a sample of a degenerate query:
from foo in collection select foo


Its called degenerate because it seemingly adds no value to the code e.g.:

var items = from foo in collection select foo;
foreach (var item in items)
{
      //Do something
}

We could have easily done (hypothetically):

foreach (var item in collection)
{
      //Do something
}

But it is required when you use linq to SQL ( or LINQ to EF or LINQ to XML etc) because these implementations of LINQ actually override the Select extension method. It looks degenerate ... but it is required for the API to hook in for expression evaluation. 

"A query that simply returns a result equal to the original data source is called degenerate query expression" 

Enjoy!


Sunday, February 13, 2011

LINQ Tutorial : The from clause

I am currently preparing for exam 70-516. Reading Programming Microsoft LINQ in Microsoft .NET Framework 4 for it and loving it. Here is something new I learnt:

The syntax of from:
from rangeVariable in dataSource

Now if dataSource is a strongly typed collection (and these are the only ones I ever create) the rangeVariable will automatically be typed according to that.
e.g. if dataSource is IEnumerable , rangeVariable will be typed as T 

What I did not know
However if dataSource is ArrayList or any other untyped datasource you will need to specify the type in the syntax :
from T rangeVariable in untypedDataSource 


Cool eh.
Enjoy!

Thursday, February 10, 2011

Achievement Unlocked : .NET Framework 4, Service Communication Applications 70-513 passed!

I passed exam 70-503 a few days ago. Today I passed 70-513 which is essentially a new version of the same exam. After going through the official training Kit for 70-503 I looked at the new features of WCF 4 (mentioned quite well here) . There weren't that many questions of the new features. But they were most definitely asked. I found the question quality to be better in this exam (less ambiguous right answers).

The exam was of 140 minutes (the old one was 120 minutes) and had 50 questions (the old one was 45). I find this to be better. (The question count alone).

PS: the title of this post is something I took from this tweet. Xboxy :)

If you are looking for resources this looks pretty awesome : http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/ ... although I didn't read it before the exam... JUST found this on google :)

Enjoy!

Wednesday, February 9, 2011

Using Eloquera DB as an simple embedded database

Eloquera has a lot of goodness in it. One thing I really like is using it as an embedded database.

All of the code is available at bitbucket here

Heres the official way of doing it.

  • Add references to your project to  Eloquera.Client / Eloquera.Server / Eloquera.Common and Eloquera.config
  • Modify Eloquera.config most commonly the port and DatabasePath as shown:

  • Setup your DB connection to connect to (local)
Now step 2 and 3 aren't that hard. But I wanted to wrap these up a bit. Created a EqUtils project. Just has two functions. You can copy paste them into your own code if you want:


/// 
        /// Ensures two things :
        /// Sets up the database path in the Eloquera.config making sure its valid
        /// Makes sure that dbName points to a valid database.
        /// 
        /// The directory where you want the database file. Recommended Environment.CurrentDirectory
        /// The name of the DBfile without the .eq extension. Also called dbname
        /// Deletes the old database and creates a new one if set to true
        /// complete or relative path to Eloquera.config
        public static void SetupDB(string dbPath,string dbName,string completeConfigPath="Eloquera.config",bool overwrite = false)
        {
            if (!Directory.Exists(dbPath))
            {
                throw new IOException("The dbPath directory does not exist. dbPath requested was : " + dbPath);
            }
            if (!File.Exists(completeConfigPath))
            {
                throw new IOException("Eloquera.config is not present. Make sure this is the path to Eloquera.config: " + completeConfigPath);
            }   
         
            //First setup the DBPath
            FileStream fs = new FileStream(completeConfigPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(fs);
            fs.Close();
            XmlNode server = xmldoc.GetElementsByTagName("Server")[0];
            var currentDatabasePath = server.Attributes["DatabasePath"];
            server.Attributes["DatabasePath"].InnerText = dbPath;
            xmldoc.Save(completeConfigPath);            
            //Now create the database if it does not exist:
            if (File.Exists(Path.Combine(dbPath, dbName+".eq")) && overwrite)
            {
                using (var db = new DB("server=(local);options=none;"))
                {
                    db.DeleteDatabase(dbName, true);
                    db.CreateDatabase(dbName);
                }
            }
            else if (!File.Exists(Path.Combine(dbPath, dbName+".eq")))
            {
                using (var db = new DB("server=(local);options=none;"))
                {                   
                    db.CreateDatabase(dbName);
                }
            }
        }

        /// 
        /// Gets a new DB instance set as local embedded mode.
        /// 
        /// DB instance set as local embedded mode
        public static DB GetLocal()
        {
            return new DB("server=(local);options=none;");
        }


I think the Doc comments pretty much explain all that there is to know.

Using the SetupDB Function you can modify your Eloquera.config with the db path, Make sure that a database is present, Overwrite a database with a new one all in one go.

Using GetLocal you don't need to type in the embedded db string again and again.


Sample
You know what. The great thing about eloquera. You can let the code do the talking:


class Program
    {

        public class TestClass
        {
            [Index]
            public double Indexed { get; set; }
            public double NonIndexed { get; set; }
        }

        public static int ObjectCount = 1000;

        static void Main(string[] args)
        {
            var DbName = "PortableStore";
            EqUtil.SetupDB(Environment.CurrentDirectory, DbName, overwrite: true);

            //Create and store random junk data:         
            using (DB db = EqUtil.GetLocal())
            {
                db.OpenDatabase(DbName);
                for (int i = 0; i < ObjectCount; i++)
                {
                    TestClass item = new TestClass() { Indexed = i, NonIndexed = i };
                    db.Store(item);
                }
                db.Close();
            }           

            //Read all the random junk:
            using(DB db = EqUtil.GetLocal())
            {
                db.OpenDatabase(DbName);
                
                //Query using linq             
                var testClasses = from TestClass testClass in db select testClass;
                foreach (var item in testClasses)
                {
                    //This makes sure all data is retrieved 
                    //A cast will be required as in: (TestClass)item
                }                

                //Query using SQL:
                //For syntax visit http://eloquera.com/help/
                //Note you need to mention the namespace
                
                var sqlTestClasses = db.ExecuteQuery("Select Program.TestClass");
                foreach (var item in sqlTestClasses)
                {
                    //Console.WriteLine(((TestClass)item));
                }

                db.Close();                
            }

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }


Simple isn't it? This simple creates a new database. Overwriting the old one if required:

var DbName = "PortableStore";
EqUtil.SetupDB(Environment.CurrentDirectory, DbName, overwrite: true);


After this will see a newly created PortableStore.eq file in the same folder as your application:


The code simple creates random 1000 items of TestClass and queries them first using Linq and then SQL.
Cool eh? And did I mention ... the reads are REALLY fast. Try it out.

Notes

  • In case you configure your application like this (Environment.CurrentDirectory) note that UAC (Useraccess control on windows Vista and latter) does not allow an application not running as administrator to edit any files in the "Program Files" folder. So, it is best to distribute your application as xcopy deploy OR mention your uses to not install in that folder OR at the very least make the SetupDB step optional / configurable. 
  • It is always good practice to use using:
//Create and store random junk data:         
            using (DB db = EqUtil.GetLocal())
            {
                db.OpenDatabase(DbName);
                for (int i = 0; i < ObjectCount; i++)
                {
                    TestClass item = new TestClass() { Indexed = i, NonIndexed = i };
                    db.Store(item);
                }
                db.Close();
            }   
The general format is Using  { open ; work ; close } 
  • The SetupDB function makes sure that you can call OpenDatabase and there is no need to check if the database file is present. 

Enjoy!

Tuesday, February 8, 2011

MVVMLight Extensions, Part: The MVVM Validation

MVVMLight is great. It is at the very least the most effective MVVM framework that is Blend / Visual Studio Design time friendly. The project focuses a lot on providing the minimum amount of built in functionality to give you the ability to make effective MVVM applications. This means that there are some areas (like validation) where MVVMLight does not add anything more that what is already available with WPF / Silverlight. So wanting to extend the library with your own extensions is a normal desire.

The Code (hosted by bitbucket)

Here is my attempt. You don't have to use it. I don't expect you to (you might want to add the code to your bag o tricks in your own mvvmlightextensions).

Here I explain what comes with the package:

A better way to add validation (Source)
The sample (kept as bare bones as possible to be simple):


We look at the model / the viewmodel and the view in turn.


Before you read about the Model and ViewModel check out snippets section. 


The Model
Its about time you move your models to object databases. With that just (2 things) :

  • Inherit from ModelBase and you neet all the goodness in the INotifyPropertyChanged and IDataErrorInfo.  

Just look at student.cs. There are two simple properties Name (string) / AdmissionDate (DateTime?) (both added with mvvminpcs snippet)

and implement:
  • override of string this[string columnname] added using mvvmde and mvvmdei snippets. Fill it up with your validation logic:



All in all about 100 keystrokes max (if you don't count the error strings :))
The ViewModel

  • Expose the Model as a property on the View (use a snippet of course):
  • Expose your commands (again use a snippet):


  • IMPORTANT Use base.UIValidataionErrorCount and ModelObject.Error.Count to determine if there are any errors (e.g return base.UIValidationErrorCount == 0 && this.Student.Errors.Count == 0 is used in the sample to determine if the save command can execute)



The View
Nothing much to do except that
  • inherit from ViewBase rather than UserControl:

  • Define a style for validation template and apply it in your View Xaml:
    <mle:ViewBaseEx.Resources>
            <!--Create a validataion control template for a TextBlock-->
            <ControlTemplate x:Key="validationTemplate">
                <DockPanel>
                    <TextBlock Margin="5,0,5,0" Foreground="Red" FontSize="16" VerticalAlignment="Center" Text="*" ToolTip="{Binding ElementName=errorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
                    <AdornedElementPlaceholder x:Name="errorAdorner" />
                </DockPanel>
            </ControlTemplate>
            <!--Set the Validation Error Template to the control template we just created-->
            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource validationTemplate}" />
            </Style>
        </mle:ViewBaseEx.Resources>
  • And in all the bindings that are bound to the Model (view the ViewModel) add the following:
    NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True

That wasn't so hard was it.
Enjoy!

Monday, February 7, 2011

MVVMLight Extensions, Part: The Snippets


MVVMLight is great. It is at the very least the most effective MVVM framework that is Blend / Visual Studio Design time friendly. The project focuses a lot on providing the minimum amount of built in functionality to give you the ability to make effective MVVM applications. This means that there are some areas (like validation) where MVVMLight does not add anything more that what is already available with WPF / Silverlight. So wanting to extend the library with your own extensions is a normal desire. 


Here is my attempt. You don't have to use it. I don't expect you to (you might want to add the code to your bag o tricks in your own mvvmlightextensions).

The snippets can be categorized by Model and General: 

General
mvvmrc
For mvvm relay command expansion shown, Just fill in name / ExecuteFunction and CanExecuteFunction: 

Utilized in sample:

mvvminpcs:
For INotifyPropertyChanged using stacktrace: 
The RaisePropertyChanged function is defined in ViewModelBaseEx and therefore your ViewModel/Model needs to inherit from ViewModelBaseEx 
Used in sample application: 
Model
mvvmde:
If you Model inherits from ViewModelBaseEx you can use mvvmde for the data validation logic: 
Just fill in the property , the validation condition and the error message you want displayed.
For additional properties just use the mvvmdei snippet:


Used in the sample application: 






Myth: WCF Configuration is hard , Result: False

Okay. If you do it manually by editing the app.config / web.config file. Then yes. It can be.
But there is a better graphical way to do this using the Microsoft Service Configuration Editor (SvcConfigEditor.exe). Its use is recommended to avoid annoying spelling mistake errors :)

It is available right from visual studio when you right click app.config or web.config file AFTER you have started it once i.e. by default if you right click web.config or app.config you can't see the option "Edit WCF Configuration" :
Option for "Edit WCF Configuration" is not available by default
You need to start the Service Editor at least once for the option to become available. You can start the service editor from Tools -- WCF Service Configuration Editor :
After the Editor opens you can simply close it:
Simply close this window (or you can open a .config file manually)
Now when you right click web.config or app.config you will see the option "Edit WCF Configuration":
And the web.config / app.config file will be opened in the Microsoft Service Configuration Editor :
Click to enlarge :)
Note that you can even edit the Diagnostics section of System.ServiceModel. Awesomeness :)

A Note about correlation between imperative configuration in code vs. configuration in .config:
Items in config as attributes map to properties in code.
Items as inner xml elements map to properties that are complex types in .net (i.e WCF classes rather than simple enums / ints / TimeSpans etc).
A very useful (albeit fundamental / obvious) observation.

Enjoy!

Exam 70-503 Passed

This time I got 918 / 1000. Not my highest but I am satisfied.
So, how did I prepare this one. I took two months to prepare for this exams (mostly because there were a lot of things that were pending since the last exam). It was totally worth it. I thought I knew WCF before starting on the only book I read. I learnt soo much more from this book. There is some repetition of content in the book but its not excessive. And in fact it helps to drill the data into your memory.

This book (the official guide) is the best one I have read yet. This should be pretty clear considering my score and this being the ONLY book I read on WCF itself. I feel so confident after reading this book that I am going to attempt the WCF 4 certification soon. Right after doing all the stuff (coding) that is pending this time around :). the list of new features in WCF 4 is not too big ... also there is no Official book for WCF 4 certification mentioned as of yet so I'll msdn / bing what I need to know ;) Also today is the day this becomes available hmmm :)

My friends and family had to be really patient during the last few days before the certification and I'd like to thank them. Its hard work but I am glad I went through it.

Enjoy!