Current set up at home includes my main DELL XPS upstairs, with a previous computer downstairs, which I was battling with until now, will explain later, and the old faithful laptop!!!

Now to set the scene, on the main computer, my dell xps, I had several previous windows installations lying there, after various updates, basically cause each time I updated I always doubted I did not have everything to continue with the next installation.  So basically yesterday I got my copy of windows 7 from MSDN with the intention of doing a clean and fresh install on the Dell.  The current operating system on there was Windows Vista Ultimate, and as you may know, you have the facility with windows vista and future versions to create a complete computer backup, which actually creates a virtual hard disk for you, which I was very pleased about.

As sods law would have it,  no more than 5 minutes after completing the FULL BACK UP the computer had a severe hardware failure, giving me the blue screen of death (which never gets easier to see) and shortly followed my me switching off the power.  I am presuming that the hardware failure was the graphics card, as the view even to the bios was, well, SCREWED!! I was in two minds, one gutted that I am now temporarily without my main computer, the mother ship, but at the same time, relieved that I made that complete computer backup.  Normally I simply back up what files and folders are of up most importance to me with the knowledge that the OS can simply be plugged back in , and ok the settings are lost, but I am not picky and I do not really configure the settings that much.  Open the box, use, smile, that is currently my state of mind.

Ok, so I have the computer backup VHD (Virtual Hard Disk) on my external hard drive, a laptop with Windows Vista Home Premium, a goosed dell xps desktop and finally another desktop computer downstairs with a screwed up installation of LINUX, which only has a Boot loader in the form of GNU GRUB that loads every time during boot and totally blocks the ability to boot from CD.  "BOOTMGR is missing!" is the message I got with it, and I did try, but I will point out, my knowledge of LINUX is severely limited due to the shear fact I DO NOT USE IT!  I installed it in the past, specifically CENT OS, due to a continued interest in the pursuit of C++ as I wanted to apply the programming to both windows and Linux.  I will feel like that again soon, but not yet.  I have a few hard drives which are not being used, so to save headache, I removed the nice 350GB HD from the computer which had the goofed Linux installation and banged in a modest 35 GB one, and hey presto I could boot from CD again.  Great back on track.

This is where the Windows 7 comes in as it is that which I booted the computer with.  Upon completion of the installation it was straight to superuser.com to ask, I have this VHD, HOW DO I MOUNT IT?!?!  No more than 5 minutes later I get this reply:

If you are running Windows 7 this can be done using Disk Management.

•Open Computer Management
•Select Disk Management
•Right Click on Disk Management
•Select Mount a VHD file
However if you are running anything below Windows 7 this is not supported.

http://superuser.com/questions/32913/how-to-mount-a-vhd-which-is-on-an-external-usb-hard-drive

Great stuff, so after a couple of attempts, I was able to attach the VHD and initialize the disk, and recover some files that were not under source control, BUT ARE NOW! :-)

So I have had to use a nice feature of Windows 7 which I like, is of great benefit, and also is extremely easy to use.  It looks great, it seems to be much lighter on the memory than vista, and another first impression is that the task bar is the best laid out I have seen on a windows OS.  On to the Windows 7 SDK!!

Windows 7 for me, is a real comfortable OS!!

cheers,

Andrew

P.S. It burns ISO Images to Disc natively!! - This was a last minute find before I published.


Monday, August 31, 2009 8:07:34 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

During a Google search for the free power threading library which Jefferey Richter created, and I believe patented and sold to Microsoft I saw a post which is great news, personally for me and no doubt many, many others.  It is that he is currently writing the 3rd edition of his CLR via C# Book.  I bought the 2nd edition and it is still an excellent reference with latter chapters explaining about memory management, asynchronous operations and threading.  The depth which he is able to go into and explain these topics to you is superb due to his profound knowledge of the language and programming as a whole!

So again, he is now currently writing this next edition and, from what he says in the blog, is comfortable with the deadline of matching the release with that of .NET 4. 

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2009/06/17/clr-via-c-3rd-edition.aspx

I currently have the following books from Jeffrey Richer, links to amazon.co.uk attached:

Product Details

Product Details

Cheers,

Andrew



C#
Thursday, August 27, 2009 4:36:33 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

The first part in this series which I would like to do can be found here:

Part 1 : Socket Programming with C#, JAVA, C++ and Action Script 3.0 – Establishing a base connection and communication with C# Server and AS3

The files for this solution can be downloaded here: WCFCallbackExample

I am looking into how you can work with network communication with sockets using the different languages and this post will use C# and more specifically WCF.  In this post I will look at the bi directional capability of WCF using the NetTcpBinding, I will follow up this post in the near future with an example using the Duplex WS binding (WSDualHttpBinding).  If you are in the area of Application Development and say wanting to use this for example with a chat application, the NetTcpBinding requires that both the client and the service use WCF, so for interoperability that is not really of much use, but there is more than one way to skin a cat for sure.

In this post and the example solution I am making use of threading for the purposes of the example so I can simulate many clients, as opposed to launching the application many times.  I will be making use of the Thread class, ThreadPool class, WaitHandle class, ManualResetEvent class and using a ParamterizedThreadStart and WaitCallBack delegates.  I have also made an extension method which the mode value of an IList<T>.

The theme of this example will be voters casting these vote.  Once all the votes are in, in this case 10, the votes will be counted and all the voters will be informed of the winning candidate.

NetTcpBinding

For the code in this example I am not using the configuration files, I am instantiating and configuring on the fly programmatically as I want to get a feel for accomplishing tasks both programmatically and through xml configuration as both have their benefits dependant on the situation.  The basic idea which I want to demonstrate first of all goes like this.

  1. Instantiate and open a service host to accept incoming messages
  2. Instantiate a client a proxy a call to the listening service
  3. On the server side I want to process the message call from the client and then call-back to the client using the method which I define with an interface(the contract).

The Program

The files which make up this small program include the following:

  • IVote
  • IVoteCallback
  • Client
  • ListExtension
  • Proxy
  • Server
  • ServiceHost

image

I have separated the client from the proxy, first because lol it is a proxy but also each one has a different responsibility, what you end up with though is Client calls Vote on Proxy, Proxy calls Vote on the Service.  So it is exactly that “a proxy,” i.e. the middle person.

I have used the following class for a generic Service Host from the following book, Programming WCF Services.

    public class ServiceHost<T> : ServiceHost
    {
        public ServiceHost()
            : base(typeof(T))
        { }

        public ServiceHost(params string[] baseAddresses)
            : base(typeof(T), Convert(baseAddresses))
        { }

        public ServiceHost(params Uri[] baseAddresses)
            : base(typeof(T), baseAddresses)
        { }

        static Uri[] Convert(string[] baseAddresses)
        {
            Converter<string, Uri> convert = delegate(string address)
            {
                return new Uri(address);
            };

            return Array.ConvertAll(baseAddresses, convert);
        }
    }

The call-back

This is very much an event, and as such many client can subscribe to this event.  It is the service’s responsibility to ensure all subscribers of this event are notified upon the invocation of some trigger, “Don’t call us we shall call you.”

As much as this is an event, the way you program this as opposed to normal CLR Event Subscription and Invocation is different and slightly more management is required with regards to concurrency.

The contract for the call-back is simply the following:

    public interface IVoteCallback
    {
        [OperationContract]
        void OnVotesCounted(string winner);
    }

The server will invoke this method on the clients, and the clients themselves will inherit from this interface so the server can invoke the method on it.  The implementation of this method is up to the client, but it is the responsibility of the Service Host to invoke it.

The Service Contract

The following contract is what the service needs to use, and also any proxy that is made for this service. The client invokes the contract on the proxy and in turn the proxy invokes the contract on the service.

    [ServiceContract(Name = "WCFCallbackExample.Contract.IVote",
        Namespace="uk.co.andrewrea",
        SessionMode=SessionMode.Required,
        CallbackContract=typeof(IVoteCallback))]
    public interface IVote
    {
        [OperationContract(IsOneWay=true)]
        void PlaceVote(string name);
    }

This interface requires some specific attributes for the purposes of:

  1. Being a service contract
  2. Providing operation contracts for a service
  3. Allowing the service to be used in a Duplex hosting scenario, i.e. the service host can send messages to the client as well as the client can send messages to the service
  4. Information for WCF to recognise what call-back it is dealing with.

The session mode is set to required so a call-back can be sent to the client, this is also true of the WSDualHttpBinding.

Also I will mention why I have made the operation in this contract one way below.

The Server

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
        ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Server : ServiceHost<Server>, IVote
    {
        //A collection of votes from the clients.  
        //The candidate name is the string object value
        private static List<string> _votes
            = new List<string>();

        //A list of the callbacks which the server should invoke
        //allowing the clients to be notified
        private static List<IVoteCallback> _callbacks
            = new List<IVoteCallback>();

        //For the purposes of syncronization
        private static object _syncLock = new Object();

        public Server()
            : base()
        {

        }

        public Server(params string[] addresses)
            : base(addresses)
        {

        }

        #region IVote Members

        /// <summary>
        /// This method will be proxied and called by the client
        /// </summary>
        /// <param name="name"></param>
        public void PlaceVote(string name)
        {
            lock (_syncLock)
            {
                //Get the callback from the client
                IVoteCallback callback = OperationContext.Current
                    .GetCallbackChannel<IVoteCallback>();

                //If the service does not already contain the callback add it
                if (!_callbacks.Contains(callback))
                    _callbacks.Add(callback);

                //Add the vote
                _votes.Add(name);

                //I do not want to block here, so I accept the vote and 
                //call the method to count the votes on another thread
                //
                //I origianlly used the below BUT making the operation IsOneWay
                //Achieves the same thing.  Without this or the IsOneWay,
                //this will block the client thread.
                //ThreadPool.QueueUserWorkItem(new WaitCallback(CheckVoteCount));

                if (_votes.Count == 10)
                {
                    System.Threading.Thread.Sleep(2000);
                    VotesCounted();
                }
            }
        }

        /*
         * 
         * This was called by the ThreadPool, see above
        private void CheckVoteCount(object state)
        {
            if (_votes.Count == 10)
            {
                System.Threading.Thread.Sleep(2000);
                VotesCounted();
            }
        }
         * */

        #endregion

        /// <summary>
        /// This is the callback.  It will loop through all of them and
        /// invoke.  This is the method which updates the clients
        /// </summary>
        private static void VotesCounted()
        {
            Action<IVoteCallback> invoke =
                delegate(IVoteCallback clientCallback)
                {
                    clientCallback.OnVotesCounted(_votes.MostOccurences<string>());
                };

            _callbacks.ForEach(invoke);

        }
    }

The server is keeping a list of:

  • Votes
  • Call-backs

I have plumbed in some thread safety, as each call made to the service will be from a different thread.  You will notice that there is some code I have commented out but left in there.  This is because I wanted to explain the purpose of why I have not used it and what I have used instead.  What I was doing there was ensuring that the method did not block the client thread, so I did the work of the client and then kicked off another thread to check whether or not it should count the votes.  After doing this though, I thought about the IsOneWay attribute property which did exactly what I require.  If you specify this on an operation context, the client will call and forget about the method, i.e. it will not block as it does not care about is outcome so in this way I was able to leave the check for the votes inside the client method and this did not affect the client in terms of time.

Above when I said this was like the CLR Event model in a way, I would now say that through its implementation, it is more like the Java Event Model where you specifically add listeners and the object loops through its subscribers and calls the method the listener has provided as the call-back.  I realise under the covers this is what the clr event model will do, but from a coding point of view, it is more Java’esque – The Observer Pattern.

I will show the source for the extension method, MostOccurences<T> below.

The Proxy

    public class Proxy : DuplexClientBase<IVote>, IVote
    {
        public Proxy(InstanceContext context,
            Binding binding,
            EndpointAddress endpointAddress)
            : base(context, binding, endpointAddress)
        {

        }

        #region IVote Members

        public void PlaceVote(string name)
        {
            Channel.PlaceVote(name);
        }

        #endregion
    }

I have inherited both from the service contract but also from the DuplexClientBase<T> as opposed to the ClientBase<T> which allows the client to accept call-backs from the service.  As a proxy should, the PlaceVote method calls the PlaceVote of the service.  Although I have specified a constructor which allows the supply of a Binding, I am only using NetTcpBinding for this program but I have supplied it, as this is a constructor of the base class.  The InstanceContext is used directly for the call-back, so the service can identify what object instance to use for the call-back method.

The Client

    public class Client : IVoteCallback,IVote
    {
        private Proxy _proxy;
        private string _voterName;
        private ManualResetEvent _handle;

        public Client(string voterName, string serviceEndpointAddress, ManualResetEvent handle)
        {
            _voterName = voterName;
            _handle = handle;
            InstanceContext context = new InstanceContext(this);
            _proxy = new Proxy(context,
                new NetTcpBinding(),
                new EndpointAddress(serviceEndpointAddress));

        }

        #region IVoteCallback Members

        public void OnVotesCounted(string winner)
        {
            Console.WriteLine(String.Format("{0} has been notified the winner is {1}",_voterName, winner ));
            _handle.Set();
        }

        #endregion

        #region IVote Members

        public void PlaceVote(string name)
        {
            _proxy.PlaceVote(name);
            Console.WriteLine(String.Format("From {0}: I have placed my vote for {1}!", _voterName, name));
        }

        #endregion
    }

A lot of this code, is specific just to this example but it is the instantiation of the proxy and in turn the invocation of its method, and the implementation of both the Service Contract and the Call-back contract which are important.  The threading elements are just to provide synchronization and are used so I can test the service with multiple clients(threads). 

The Extension Method (ListExtenions.cs)

        public static T MostOccurences<T>(this IList<T> list)
        {
            Dictionary<T, int> count = new Dictionary<T, int>();
            foreach (T obj in list)
            {
                if (!count.ContainsKey(obj))
                {
                    count.Add(obj, 1);
                }
                else
                {
                    count[obj]++;
                }
            }

            return count.Where(x => x.Value.Equals(count.Max(k=>k.Value))).FirstOrDefault().Key;
        }

This will give me the value of the IList<T> which occurs most often, and its use is so I can see the candidate who won.

Program.cs

This is the main program where I implement the work.  Again the threading stuff is just for the purposes of the example.

    class Program
    {
        private static Server server;

        private static string netServerAddress = "net.tcp://localhost:8000";
        private static string endpointAddress = "net.tcp://localhost:8000/VotingService";
        private static Random rnd;

        private static string[] candidates = new string[]{
            "Candidate 1",
            "Candidate 2",
            "Candidate 3"
        };

        private static ManualResetEvent[] handles = new ManualResetEvent[10];
        private static Thread[] threads = new Thread[10];
        
        static void Main(string[] args)
        {
            rnd = new Random();

            StartService();

            for (int i = 0; i < 10; i++)
            {
                handles[i] = new ManualResetEvent(false);
                threads[i] = new Thread(new ParameterizedThreadStart(CreateClientAndVote));
                threads[i].Start(i);
            }

            Console.WriteLine("Waiting for votes to come in...");

            WaitHandle.WaitAll(handles);

            server.Close();

            Console.WriteLine("Voting has ended");

            Console.ReadLine();
        }

        static void StartService()
        {
            server = new Server(netServerAddress);
            server.AddServiceEndpoint(
                "WCFCallbackExample.Contract.IVote",
                new NetTcpBinding(),
                endpointAddress);
            server.Open();
        }

        static void CreateClientAndVote(object state)
        {
            int number = (int)state;
            Client newClient = new Client(String.Format("Voter #{0}", number + 1), endpointAddress, handles[number]);
            newClient.PlaceVote(candidates[(int)(rnd.Next(candidates.Length))]);
        }
    }

image

And thats it.  I hope this is of some help and/or interest.

Cheers for now,

Andrew.



.NET | C# | WCF
Wednesday, August 26, 2009 6:23:44 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

Download the source project

Image

image

Working in Silverlight

 

 

I have seen a lot of comparisons made between ActionScript and Silverlight with specific focus on the difference in lines of code, and more specifically when referring to the drawing api.  What I thought I would do is do a little drawing and in this example I have developed a teeny tiny interface for a clock view, which has a method of simply SetTime(DateTime time)  and I have made one implementation of this Clock view which is an analogue clock.  I have used some simple ellipse equations to allow for dynamic resize and redraw and in hind sight I would refactor my code so as not to keep adding and removing the shapes which are UIElements.  I will make some more clocks with this refactoring present.  It does feel like a gauge control is on the way also, there are so many gauge controls out there including the, cool, free ones from Microsoft, well they are charting controls but never the less and absolutely amazing freebie.

So the whole purpose of this post is about programmatic drawing as opposed to using the XAML equivalent, which I might say would be worth looking at to replicate this example! 

The Code

So to the code, first I have defined a short interface as follows:

namespace SilverlightClock
{
    public interface IClockView
    {
        void setTime(DateTime time);
    }
}

Next is the xaml mark-up, and the only thing I have amended is the Root UIElement which I have used a Canvas as opposed to the default Grid.  This lets me set things out using the Canvas.LeftProperty and Canvas.TopProperty.

<UserControl x:Class="SilverlightClock.AnalogueClock"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Canvas x:Name="LayoutRoot" Background="White">

    </Canvas>
</UserControl>

Next is the mark-up and class diagram for the actual UserControl - AnalogueClock.

image  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightClock
{
    public partial class AnalogueClock : UserControl, IClockView
    {
        private DateTime _time = new DateTime(2000, 1, 1, 18, 15, 50);
        private double hour;
        private double minute;
        private double second;

        public AnalogueClock()
        {
            InitializeComponent();
            SizeChanged += new SizeChangedEventHandler(AnalogueClock_SizeChanged);
            Loaded += new RoutedEventHandler(AnalogueClock_Loaded);
        }

        void AnalogueClock_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Draw();
        }

        void AnalogueClock_Loaded(object sender, RoutedEventArgs e)
        {
            Draw();
        }

        void Draw()
        {
            LayoutRoot.Children.Clear();
            var step = 360 / 60;
            var innerRadiusX = (Width * 0.7) / 2;
            var innerRadiusY = (Height * 0.7) / 2;
            var outerRadiusX = (Width * 0.8) / 2;
            var outerRadiusY = (Height * 0.8) / 2;
            var textRadiusX = (Width * 0.9) / 2;
            var textRadiusY = (Height * 0.9) / 2;
            var outerCasing = new Ellipse();
            outerCasing.Stroke = new SolidColorBrush(Colors.Black);
            outerCasing.Width = (Width * 0.8);
            outerCasing.Height = (Height * 0.8);
            outerCasing.SetValue(Canvas.LeftProperty, Width * 0.1);
            outerCasing.SetValue(Canvas.TopProperty, Height * 0.1);
            LayoutRoot.Children.Add(outerCasing);

            for (var i = 0; i < 60; i++)
            {
                var line = new Line
                {
                    Stroke = new SolidColorBrush(Colors.Black),
                    X1 = (Width / 2) + Math.Sin((step * i) * (Math.PI / 180)) * innerRadiusX,
                    Y1 = (Height / 2) + Math.Cos((step * i) * (Math.PI / 180)) * innerRadiusY,
                    X2 = (Width / 2) + Math.Sin((step * i) * (Math.PI / 180)) * outerRadiusX,
                    Y2 = (Height / 2) + Math.Cos((step * i) * (Math.PI / 180)) * outerRadiusY
                };


                if (i % 5 == 0)
                {
                    line.X1 = (Width / 2) + Math.Sin((step * i) * (Math.PI / 180)) * ((Width * 0.6) / 2);
                    line.Y1 = (Height / 2) + Math.Cos((step * i) * (Math.PI / 180)) * ((Height * 0.6) / 2);

                    var textblock = new TextBlock();
                    textblock.Text = i == 0 ? "12" : ((double)(i / 60D) * 12D).ToString();

                    var textX = (Width / 2) + Math.Sin(-((step * i + 180) % 360) * (Math.PI / 180)) * textRadiusX;
                    var textY = (Height / 2) + Math.Cos(-((step * i + 180) % 360) * (Math.PI / 180)) * textRadiusY;

                    textblock.SetValue(Canvas.LeftProperty, textX - textblock.ActualWidth / 2);
                    textblock.SetValue(Canvas.TopProperty, textY - textblock.ActualHeight / 2);

                    LayoutRoot.Children.Add(textblock);
                }

                LayoutRoot.Children.Add(line);
            }


            DrawHourHand();
            DrawMinuteHand();
            DrawSecondHand();
            DrawMilliSeconds();
            DrawLogo();
        }

        private void DrawLogo()
        {
            var textBlockLogo = new TextBlock();
            textBlockLogo.Text = "andrewrea.co.uk";
            textBlockLogo.FontFamily = new FontFamily("Arial");
            textBlockLogo.FontSize = 9D;
            textBlockLogo.SetValue(Canvas.LeftProperty, (Width - textBlockLogo.ActualWidth) / 2);
            textBlockLogo.SetValue(Canvas.TopProperty, (Height - textBlockLogo.ActualHeight) / 3);
            LayoutRoot.Children.Add(textBlockLogo);
        }

        private void DrawHourHand()
        {
            //Change hour value to percentage for use with 360
            double hourPercentage = (hour + (minute / 60D)) / 12D;

            //Get the Hour degree value
            double hourDegree = 360 * hourPercentage;

            DrawHand(Width / 5.5D, Height / 5.5D, -hourDegree, Colors.Black, 3);
        }

        private void DrawMinuteHand()
        {
            //Change minute value to percentage for use with 360
            double minutePercentage = (minute + (second / 60D)) / 60;
            //Get the minute percentage
            double minuteDegree = 360 * minutePercentage;

            DrawHand(Width / 4.5D, Height / 4.5D, -minuteDegree, Colors.Blue, 2);
        }

        private void DrawSecondHand()
        {
            double secondPercentage = second / 60D;
            //Get the minute percentage
            double secondDegree = 360 * secondPercentage;

            DrawHand(Width / 3.5D, Height / 3.5D, -secondDegree, Colors.Red, 1);
        }

        private void DrawMilliSeconds()
        {
            //Figure out the second hand
            double millisecond = _time.Millisecond;
            //Change minute value to percentage for use with 360
            double millisecondPercentage = millisecond / 1000;
            //Get the minute percentage
            double millisecondDegree = 360 * millisecondPercentage;

            var milliContainer = new Ellipse();
            milliContainer.Width = (Width * 0.1D) + 1;
            milliContainer.Height = (Height * 0.1D) + 1;
            milliContainer.Stroke = new SolidColorBrush(Colors.Black);
            milliContainer.SetValue(Canvas.LeftProperty, (Width * 0.65) - (Width * 0.05D));
            milliContainer.SetValue(Canvas.TopProperty, (Height * 0.65) - (Height * 0.05D));

            var hand = new Line
            {
                Stroke = new SolidColorBrush(Colors.Green),
                X1 = Width * 0.65,
                Y1 = Height * 0.65,
                X2 = (Width * 0.65) + -Math.Sin(-millisecondDegree * (Math.PI / 180)) * (Width * 0.05D),
                Y2 = (Height * 0.65) + -Math.Cos(-millisecondDegree * (Math.PI / 180)) * (Height * 0.05D)
            };

            LayoutRoot.Children.Add(milliContainer);
            LayoutRoot.Children.Add(hand);
        }

        private void DrawHand(double radiusX, double radiusY, double angle, Color color, double thickness)
        {
            var hand = new Line
            {
                Stroke = new SolidColorBrush(color),
                X1 = Width / 2,
                Y1 = Height / 2,
                X2 = (Width / 2) + -Math.Sin(angle * (Math.PI / 180)) * radiusX,
                Y2 = (Height / 2) + -Math.Cos(angle * (Math.PI / 180)) * radiusY
            };
            hand.StrokeThickness = thickness;

            LayoutRoot.Children.Add(hand);
        }

        #region IClockView Members

        public void SetTime(DateTime time)
        {
            _time = time;
            hour = _time.Hour;
            minute = _time.Minute;
            second = _time.Second;
            
            Draw();
        }

        #endregion
    }
}

Next is the xaml mark-up for the actual page.xaml .  Really I could have created a Presenter for this, but I haven’t.  The setup is primed for one since I am declaring an interface for an actual clock view, and like many examples in many other programming languages, a good second view for this interface would be a DigitalClock user control. I think that it would be a nice second example to use to have a deeper look into how we can skin it up to such an extent for it to resemble to classic 80’s style red digit alarm clock.

So the xaml mark-up.  This is simply the grid layout, labels and instances of the user control.

<UserControl x:Class="SilverlightClock.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:x2="clr-namespace:SilverlightClock"
    Width="600" Height="460">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition />
            <RowDefinition Height="30" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="London" Grid.Column="0" Grid.Row="0" 
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Center" FontWeight="ExtraBlack"></TextBlock>
        <x2:AnalogueClock Height="200" Width="200" x:Name="ClockLondon" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="Stretch"
                          Grid.Column="0" Grid.Row="1"></x2:AnalogueClock>
        <TextBlock Text="New York" Grid.Column="1" Grid.Row="0" 
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Center" FontWeight="ExtraBlack"></TextBlock>
        <x2:AnalogueClock Height="200" Width="200" x:Name="ClockNewyork" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="Stretch"
                          Grid.Column="1" Grid.Row="1"></x2:AnalogueClock>
        <TextBlock Text="Sydney" Grid.Column="2" Grid.Row="0" 
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Center" FontWeight="ExtraBlack"></TextBlock>
        <x2:AnalogueClock Height="200" Width="200" x:Name="ClockSydney" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="Stretch"
                          Grid.Column="2" Grid.Row="1"></x2:AnalogueClock>
        <TextBlock Text="Paris" Grid.ColumnSpan="3" Grid.Row="2" 
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Center" FontWeight="ExtraBlack"></TextBlock>
        <x2:AnalogueClock Height="200" Width="600" x:Name="ClockParis" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="Stretch"
                          Grid.ColumnSpan="3" Grid.Row="3"></x2:AnalogueClock>
    </Grid>
</UserControl>

The last part is the code behind for this page.xaml, and it is something which I think I should have probably used a storyboard for, but I am not too sure. Either way I have used a timer and it is a bit too processor intensive, I think I would want to use the Silverlight equivalent of the flash Event.ENTER_FRAME and I say equivalent because Silverlight does not use frames ;-)

namespace SilverlightClock
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void dt_Tick(object sender, EventArgs e)
        {
            ClockLondon.SetTime(DateTime.Now);
            ClockNewyork.SetTime(DateTime.Now.AddHours(-5));
            ClockSydney.SetTime(DateTime.Now.AddHours(10));
            ClockParis.SetTime(DateTime.Now.AddHours(2));
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            System.Windows.Threading.DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 100); // 500 Milliseconds
            dt.Tick += new EventHandler(dt_Tick);
            dt.Start();
        }
    }
}

I am setting the time zones using the DateTime methods and the rest is simply using the interface to set the time of the view. 

I hope this is of some use and hopefully of interest to you.

Cheers for now,

Andrew



.NET | C# | Silverlight
Wednesday, August 12, 2009 9:54:27 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

The following are a collection of resources and tips if you want to use memcached as the 2nd level caching strategy for NHibernate.  I must admit it was not as easy as it should have been, but only because the required files are not in one place.

Regarding Memcached

Download for windows
http://jehiah.cz/projects/memcached-win32/

Once downloaded you can do the following to install

1. Save exe to C:\memcached\memcached.exe
2. Start > run > cmd
3. cd\
    cd c:\memcached
    C:\memcached>memcached.exe -d install

You can run memcached –h for a help file, the possible options are as follows:

image

NOTE : If you are using Vista then you need to start the command prompt with elevated privileges

Go to Control Panel > Administrative Tools > Services

Locate the memcached service and notice is should be automatic and start it by right clicking and select start

Regarding NHibernate

Link to NHibernate Download - I am using 2.1.0.GA
http://nhforge.org/media/g/nhibernate/default.aspx

NHibernate Caches
http://nhforge.org/media/g/caches/default.aspx

Example config entry:
The memcached client will look for this entry when it initializes, without this it will throw a NullReferenceException.

<section name="memcache"
     type="NHibernate.Caches.MemCache.MemCacheSectionHandler,NHibernate.Caches.MemCache" /> 

Properties:
Configuration properties then of the memcached client are here.  Not too sure about the weight property but I think this is key to when you add more servers.

  <memcache>
    <memcached host="127.0.0.1" port="11211" weight="2" />
  </memcache> 

Using the Cache element inside the mapping file:
I have chosen to set caching switch inside the mapping files for my business objects.  Their are a few options here which you can find inside the docs, so please read up on which is best for you, i should do the same lol ;-)

  <class name="uk.co.andrewrea.forum.BusinessLogic.Domain.User, uk.co.andrewrea.forum.BusinessLogic" table="[User]">
    <cache usage="read-write"/>

Example hibernate config file:
This is my current hibernate config file I am using, just so it can give you an idea of what one would look like which is working with both lazy loading and distributed 2nd level caching and also using MS SQL 2005.  I have stored my mapping files inside a separate assembly hence the mapping element.

<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate1">
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">
      Server=REA_ANDREW-PC\SQL_EXPRESS_ADV;initial catalog=nhibernate;Integrated Security=true
    </property>
    <property name="adonet.batch_size">10</property>
    <property name="show_sql">false</property>
    <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
    <property name="use_outer_join">true</property>
    <property name="command_timeout">60</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <property name="cache.use_query_cache" >true</property>
    <property name="cache.use_second_level_cache">true</property>
    <property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>
    <mapping assembly="uk.co.andrewrea.forum.BusinessLogic.NHibernate"/>
  </session-factory>
</hibernate-configuration> 

I hope this helps other who are looking to use NHibernate and its caching provider contributions.  Make sure that the versions of NHibernate which the contributions are expecting are correct.  If you have multiple projects inside your solution make sure all of the references are in sync!

Cheers,

Andrew


Tuesday, August 11, 2009 12:29:05 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

I am currently deep into TDD with ASP.NET MVC and Moq as the mocking framework I have chosen.  I have been pondering on some valid methods in order to integrate both page index and also page size into the request. Page index and page size will be unique to each action for the purposes of this blog post and example.  I wanted to have the page index in the url, but the actual page size stored in session.  I have seen in some demonstration apps that the page size has been made constant inside the actual action and unfortunately I feel this is no good as a nice UI feature is being able to see more items per page of a list of items. 

So in the session I have put it and so I wanted to test this out and check that I am infact getting the expected results.  First off I made a simple contract for the paged data called IPagedModel and also an implementing base class called PagedModel:

    public interface IPagedModel
    {
        int TotalCount { get; }
        int TotalPages { get; }
        int PageIndex { get; }
        int PageSize { get; }
    }
    public class PagedModel : IPagedModel
    {
        private int _totalCount;
        private int _pageIndex;
        private int _pageSize;

        public PagedModel(int pageIndex, int pageSize, int totalCount)
        {
            _totalCount = totalCount;
            _pageIndex = pageIndex;
            _pageSize = pageSize;
        }

        #region IPagedModel Members

        public int TotalCount
        {
            get { return _totalCount; }
        }

        public int TotalPages
        {
            get { return (int)Math.Ceiling((decimal)_totalCount / (decimal)_pageSize); }
        }

        public int PageIndex
        {
            get { return _pageIndex; }
        }

        public int PageSize
        {
            get { return _pageSize; }
        }

        #endregion
    }

And the name of the test is this:

[TestMethod]
public void IndexAction_For_Space_1_Page_2_PageSize_2_Should_Have_PageIndex_1_PageSize_2_TotalCount_9()

I want to submit the required page number to the controller using a base 1 index and then using it inside the controller action using a zero based index. The method for the Index action which I will be testing expects an id for the object which it will be targeting but also a page number which is a nullable type in case it is not found inside the url and so will default to 0.  It is in this action where I am using the Session object to get the desired page size for the action. 

        public ActionResult Index(int id, int? pageIndex)
        {
            if (pageIndex == null)
                pageIndex = 0;

            if (pageIndex > 0)
                pageIndex = pageIndex - 1;

            int pageSize = Session["SpaceController!Index!PageSize"] == null ? 10 : Convert.ToInt32(Session["SpaceController!Index!PageSize"]);

            var space = _repository.GetSpace(id);
            if (space == null)
                return View("NotFound");

            long count;

            var forums = _repository.Get(space, pageIndex ?? 0, pageSize, out count);

            return View(new SpaceIndexViewModel(forums, pageIndex ?? 0, pageSize, (int)count));
        }

First thing is to check if the pageIndex is null and if so make it 0.  Next we want to make the conversion from a base 1 index to a base zero index which we will then use against the repository’s paging method, so basically if the page index is greater than 0, we want to minus 1 from it and use that.  We then check the session object for a valid pageSize for the action, specific to the controller.  From there on in I perform repository specific code and send the model onto the view.  To test this I want to be able to mock the controller context but also the session state and also I want to control the value return when a get on the session value "SpaceController!Index!PageSize" is made.  From looking at the Nerd Dinner application I have made a controller method to return me an instance on a controller, a test repository together with pre made test data I know and expect.  I have extended the method slightly so that I can supply both a username to indicate the HttpContext is authenticated but also session name value pairs.  I have used the Pair object for this but the NameValuePair would probably have been better.

        SpaceController CreateSpaceControllerAs(string userName, List<Pair> sessionValues)
        {
            var mock = new Mock<ControllerContext>();
            var mockSession = new Mock<HttpSessionStateBase>();
            mock.Setup(cts => cts.HttpContext.Session).Returns(mockSession.Object);
            mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
            mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

            foreach (Pair sessionValue in sessionValues)
            {
                mock.SetupGet(p => p.HttpContext.Session[sessionValue.First as string]).Returns(sessionValue.Second);
            }

            // Arrange
            var controller = CreateSpaceController();
            controller.ControllerContext = mock.Object;

            return controller;
        }

This tells the controller context to use the mock session object and also to use the supplied values for the expected get calls.  The actual test then consumes this builder method like so.

        [TestMethod]
        public void IndexAction_For_Space_1_Page_2_PageSize_2_Should_Have_PageIndex_1_PageSize_2_TotalCount_9()
        {
            var controller = CreateSpaceControllerAs(FakeForumData.FakeUser.UserName, new List<Pair>(new[]{
                 new Pair{
                      //Session Name
                      First = "SpaceController!Index!PageSize",
                      //Session Value
                      Second = 2
                 }
            }));
            // Act
            //Get first page
            ViewResult result = (ViewResult)controller.Index(1,2);

            IPagedModel model = (IPagedModel)result.ViewData.Model;

            // Assert
            Assert.AreEqual(1, model.PageIndex);
            Assert.AreEqual(2, model.PageSize);
            Assert.AreEqual(9, model.TotalCount);
        }

I am not saying I think this is the best method for storing varying page size personalization by the user, but it is something which has got me mocking the session state successfully so I am happy with that!  I hope this is of some use to others making their way though ASP.NET MVC!

Cheers

Andrew



.NET | ASP.NET MVC | C#
Monday, August 10, 2009 4:43:59 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer