<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4173999979991669893</atom:id><lastBuildDate>Wed, 15 May 2013 08:54:47 +0000</lastBuildDate><category>.net 4</category><category>flash</category><category>mvc.net</category><category>xaml</category><category>javascript</category><category>net</category><category>s3</category><category>html5</category><category>go grid</category><category>.net 3.5</category><category>workflow</category><category>ec2</category><category>bug</category><category>openrasta</category><category>SpecFlow</category><category>mediainfo</category><category>projects</category><category>gogrid</category><category>idea sharing</category><category>windows server</category><category>ASP.NET</category><category>windows 7</category><category>c#</category><category>atdd</category><category>sql server 2008</category><category>borrow a pet</category><category>iphone</category><category>TDD</category><category>spec#</category><category>amazon</category><category>video</category><category>.net</category><category>DDD</category><category>bdd</category><category>dotnet</category><category>recruitment</category><category>update</category><category>repository</category><category>resharper</category><category>wcf</category><category>sharing</category><category>linq</category><category>rackspace</category><category>mysql</category><category>silverlight</category><category>azure</category><category>cloudfront</category><category>aop</category><category>datetime2</category><category>poco</category><category>cloud</category><category>dynamsoft</category><category>ideas</category><category>offtopic</category><category>flex</category><category>ideajumble.com</category><category>beta</category><category>spec sharp</category><category>rest</category><category>mvc</category><category>db4o</category><category>kandaalpha</category><category>sys admin</category><category>sql</category><category>html</category><category>visual studio 2010</category><category>3.0</category><category>microsoft</category><category>nirvanix</category><category>release candidate</category><category>threesharp</category><category>entity framework</category><category>velocity</category><category>castle windsor</category><category>ioc</category><category>WatiN</category><title>Will Beattie's Technical Blog</title><description>Formerly Tales From the Bleeding Edge. Tales and tidbits from using the latest technologies including C#, .NET 4.0, ASP.NET MVC, jQuery, Entity Framework, ADO.NET DataServices, SQL Server 2008, WCF, Silverlight, Flex, Amazon S3, Amazon EC2, GoGrid, Windows Workflow Foundation, Windows Azure, RackspaceCloud, Cloud Sites db4o, MyGSI, HTML5, CloudFront, OpenRasta and more....</description><link>http://blog.willbeattie.net/</link><managingEditor>noreply@blogger.com (Will Beattie)</managingEditor><generator>Blogger</generator><openSearch:totalResults>65</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/willbeattiesblog" /><feedburner:info uri="willbeattiesblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-5232524615218204883</guid><pubDate>Tue, 28 Jun 2011 14:00:00 +0000</pubDate><atom:updated>2011-06-28T22:00:08.097+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">azure</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">.net 4</category><title>Windows Azure AppFabric Service Bus Queues API</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Recently Microsoft released a new &lt;a href="http://blogs.msdn.com/b/appfabric/archive/2011/06/20/announcing-the-windows-azure-appfabric-june-ctp.aspx" target="_blank"&gt;App Fabric SDK 2.0 CTP&lt;/a&gt; including some great new features,&lt;/p&gt;  &lt;p&gt;You can grab all the bits and pieces from &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=D89640FC-C552-446E-AEAD-B1E0D940F31B" target="_blank"&gt;here&lt;/a&gt; and/or read the &lt;a href="http://msdn.microsoft.com/en-us/library/gg278340.aspx" target="_blank"&gt;release notes&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Some of the highlights include:&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Publish/Subscribe which are called Topics &lt;/li&gt;    &lt;li&gt;Message Queues &lt;/li&gt;    &lt;li&gt;Visual Studio Tools &lt;/li&gt;    &lt;li&gt;AppFabric Application Manager &lt;/li&gt;    &lt;li&gt;Support for running WCF &amp;amp; WF &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The part that interested me the most is the Queues feature and that is what I’m going to be exploring in this post. &lt;/p&gt;  &lt;h3&gt;Overview of Queues&lt;/h3&gt;  &lt;p&gt;Message Queues are not a new concept allow for more reliable and scalable communication between distributed systems than pure request/response. Solutions like MSMQ, NServiceBus already exist to solve this problem for locally connected systems.&amp;#160; What the Queues API provides is that it provides similar features but the messages are being transported across the internet and persisted in the cloud.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;There is currently a &lt;a href="http://msdn.microsoft.com/en-us/library/ee794877.aspx" target="_blank"&gt;Message Buffer&lt;/a&gt; available in Azure but this has serious limitations: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Messages only persisted for a maximum 10 minutes &lt;/li&gt;    &lt;li&gt;Maximum of 50 messages &lt;/li&gt;    &lt;li&gt;Requires the client to be connected &lt;/li&gt;    &lt;li&gt;Charged per connection not per message &lt;/li&gt;    &lt;li&gt;Complex API &lt;/li&gt;    &lt;li&gt;Max message size of 8 KB&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The Queues API addresses a number of these issues by adding.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Long term persistence (No clarification on the SLA yet) &lt;/li&gt;    &lt;li&gt;Simpler API &lt;/li&gt;    &lt;li&gt;Max message size of 256 KB&lt;/li&gt;    &lt;li&gt;Sessions&lt;/li&gt;    &lt;li&gt;Larger size of queue (100 MB currently but set to increase)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;To start testing out the Queues feature you need to first Login to the &lt;a href="https://portal.appfabriclabs.com/" target="_blank"&gt;AppFabricLabs&lt;/a&gt; portal and create a test &lt;a href="http://msdn.microsoft.com/en-us/library/gg278355.aspx" target="_blank"&gt;Service Namespace&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Then you will need to add &lt;strong&gt;Microsoft.ServiceBus&lt;/strong&gt; and &lt;strong&gt;Microsoft.ServiceBus.Messaging&lt;/strong&gt; dlls to your project. They can be found in C:\Program Files\Windows Azure AppFabric SDK\V2.0\Assemblies\NET4.0&lt;/p&gt;  &lt;h3&gt;Wrapping It Up&lt;/h3&gt;  &lt;p&gt;Before starting on the implementation I’m going to define a simple interface around the&lt;strong&gt; ServiceBus&lt;/strong&gt; bits and also add an &lt;strong&gt;IMessage&lt;/strong&gt; interface which all Messages will need to implement. &lt;/p&gt;  &lt;h4&gt;IServiceBus&lt;/h4&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IServiceBus
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;void &lt;/span&gt;Send(&lt;span style="color: blue"&gt;string &lt;/span&gt;queueName, &lt;span style="color: #2b91af"&gt;IMessage &lt;/span&gt;message);
        
        T Receive&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;string &lt;/span&gt;queueName) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: #2b91af"&gt;IMessage&lt;/span&gt;; 
    }&lt;/pre&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;h4&gt;IMessage&lt;/h4&gt;

&lt;p&gt;Although not required by the API it’s good practice to have a unique identifier for each message. 
  &lt;br /&gt;When architecting message based systems you need to allow for idempotence meaning that an operation should be able to be executed multiple times without changing the result. Most message queue systems guarantee that the messages will be delivered “at least once” so you need to allow for this in your code and having an unique identifier on the message makes implementing this a trivial exercise.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IMessage
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;Id { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    }&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Trebuchet MS"&gt;&lt;strong&gt;Note:&lt;/strong&gt; All messages must be Serializable&lt;/font&gt;&lt;/pre&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;Authentication&lt;/h3&gt;

&lt;p&gt;In order to authenticate against the service bus you need three values: &lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Issuer Name &lt;/li&gt;

  &lt;li&gt;Issuer Key &lt;/li&gt;

  &lt;li&gt;Service Namespace &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The service namespace is just the name which you created in the portal, in this example it’s “&lt;strong&gt;appfabricdemo1&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;The issuer name &amp;amp; key can be found under the Default Key section in the Portal. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/-DZBzYDNj9H8/Tgh8bK0PMUI/AAAAAAAAAbc/HY09atBjwz4/s1600-h/default_key3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="default_key" border="0" alt="default_key" src="http://lh6.ggpht.com/-vMQAdoTPoEw/Tgh8bv53QDI/AAAAAAAAAbg/2hgBRj5e3pU/default_key_thumb1.jpg?imgmax=800" width="448" height="187" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;There is a little bit of ceremony in setting up the correct objects but I’ve put this into a single method called InitClient which is called from the Send and Receive methods. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       private readonly string &lt;/span&gt;issuerKey;
       &lt;span style="color: blue"&gt;private readonly string &lt;/span&gt;issuerName;
       &lt;span style="color: blue"&gt;private readonly string &lt;/span&gt;serviceNamespace;
       &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TransportClientCredentialBase &lt;/span&gt;clientCredentials;
       &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MessagingFactory &lt;/span&gt;messagingFactory;
       &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ServiceBusNamespaceClient &lt;/span&gt;namespaceClient;
       &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Queue&lt;/span&gt;&amp;gt; queueList; 

       &lt;span style="color: blue"&gt;public &lt;/span&gt;AzureServiceBus(&lt;span style="color: blue"&gt;string &lt;/span&gt;issuerName, &lt;span style="color: blue"&gt;string &lt;/span&gt;issuerKey, &lt;span style="color: blue"&gt;string &lt;/span&gt;serviceNamespace)
       {
           &lt;span style="color: blue"&gt;this&lt;/span&gt;.issuerName = issuerName;
           &lt;span style="color: blue"&gt;this&lt;/span&gt;.issuerKey = issuerKey;
           &lt;span style="color: blue"&gt;this&lt;/span&gt;.serviceNamespace = serviceNamespace;
       }&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       private void &lt;/span&gt;InitClient()
       {
           clientCredentials = &lt;span style="color: #2b91af"&gt;TransportClientCredentialBase
               &lt;/span&gt;.CreateSharedSecretCredential(issuerName, issuerKey);

           &lt;span style="color: blue"&gt;var &lt;/span&gt;uri = &lt;span style="color: #2b91af"&gt;ServiceBusEnvironment
               &lt;/span&gt;.CreateServiceUri(&lt;span style="color: #a31515"&gt;&amp;quot;https&amp;quot;&lt;/span&gt;, serviceNamespace, &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty);
           
           &lt;span style="color: blue"&gt;var &lt;/span&gt;runtimeUri = &lt;span style="color: #2b91af"&gt;ServiceBusEnvironment
               &lt;/span&gt;.CreateServiceUri(&lt;span style="color: #a31515"&gt;&amp;quot;sb&amp;quot;&lt;/span&gt;, serviceNamespace, &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty);

           namespaceClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ServiceBusNamespaceClient&lt;/span&gt;(uri, clientCredentials);

           messagingFactory = &lt;span style="color: #2b91af"&gt;MessagingFactory&lt;/span&gt;.Create(runtimeUri, clientCredentials);
       }&lt;/pre&gt;

&lt;p&gt;The key classes here are: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagingfactory.aspx" target="_blank"&gt;Microsoft.ServiceBus.Messaging.MessagingFactory&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.servicebusnamespaceclient.aspx" target="_blank"&gt;Microsoft.ServiceBus.ServiceBusNamespaceClient&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Creating the Queue&lt;/h3&gt;

&lt;p&gt;Before we can start sending and receiving messages you first have to create a queue. The API doesn’t currently have a method to check if a queue exists already so it has to be hand rolled as calling CreateQueue throws an exception if it already exists. &lt;/p&gt;

&lt;p&gt;This is fairly easily achieved with two simple methods&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Queue &lt;/span&gt;GetOrCreateQueue(&lt;span style="color: blue"&gt;string &lt;/span&gt;path)
       {
           path = path.ToLower();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;queues = GetQueues();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;queueExists = queues.Any(q =&amp;gt; q.Path == path);

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(queueExists)
           {
               &lt;span style="color: blue"&gt;return &lt;/span&gt;queues.FirstOrDefault(q =&amp;gt; q.Path == path);
           }

           &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = namespaceClient.CreateQueue(path);

           queues.Add(queue);

           &lt;span style="color: blue"&gt;return &lt;/span&gt;queue;
       }

       &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Queue&lt;/span&gt;&amp;gt; GetQueues()
       {
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(queueList != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               &lt;span style="color: blue"&gt;return &lt;/span&gt;queueList;
           }

           queueList = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Queue&lt;/span&gt;&amp;gt;();
           &lt;span style="color: blue"&gt;var &lt;/span&gt;queues = namespaceClient.GetQueues();

           &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;queue &lt;span style="color: blue"&gt;in &lt;/span&gt;queues)
           {
               queueList.Add(queue);
           }

           &lt;span style="color: blue"&gt;return &lt;/span&gt;queueList;
       }&lt;/pre&gt;

&lt;p&gt;As the &lt;strong&gt;GetQueues&lt;/strong&gt; method needs to make a remote call I keep an in-memory collection of the Queue objects so that it only calls the first time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;Queue names are converted to lowercase when created. &lt;/p&gt;

&lt;h3&gt;Sending a Message&lt;/h3&gt;

&lt;p&gt;In order to send a message you need to create a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.aspx" target="_blank"&gt;QueueClient&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesender.aspx" target="_blank"&gt;MessageSender&lt;/a&gt; and then convert the message to a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.aspx" target="_blank"&gt;BrokeredMessage&lt;/a&gt;.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;Send(&lt;span style="color: blue"&gt;string &lt;/span&gt;queueName, &lt;span style="color: #2b91af"&gt;IMessage &lt;/span&gt;message)
        {
            InitClient();

            &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = GetOrCreateQueue(queueName);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;queueClient = messagingFactory.CreateQueueClient(queue);

            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;messageSender = queueClient.CreateSender())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;brokeredMessage = ConvertToBrokeredMessage(message);

                messageSender.Send(brokeredMessage);
            }

            queueClient.Close();
            messagingFactory.Close();
        }

        &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BrokeredMessage &lt;/span&gt;ConvertToBrokeredMessage(&lt;span style="color: #2b91af"&gt;IMessage &lt;/span&gt;message)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;brokeredMessage = &lt;span style="color: #2b91af"&gt;BrokeredMessage&lt;/span&gt;.CreateMessage(message);

            brokeredMessage.MessageId = message.Id.ToString();

            &lt;span style="color: blue"&gt;return &lt;/span&gt;brokeredMessage;
        }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.aspx" target="_blank"&gt;BrokeredMessage&lt;/a&gt; has a bunch of useful properties, most notable of which are: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ContentType &lt;/li&gt;

  &lt;li&gt;CorrelationId &lt;/li&gt;

  &lt;li&gt;DeliveryCount &lt;/li&gt;

  &lt;li&gt;Properties – which is a Dictionary&amp;lt;string, object&amp;gt; &lt;/li&gt;

  &lt;li&gt;MessageId &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Receiving a Message&lt;/h3&gt;

&lt;p&gt;Receiving a message is much the same as sending a message in that it requires a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.aspx" target="_blank"&gt;QueueClient&lt;/a&gt; &amp;amp; &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagereceiver.aspx" target="_blank"&gt;MessageReceiver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two different modes when receiving a message. 
  &lt;br /&gt;ReceiveAndDelete which deletes the message immediately after reading or PeekLock which only locks the message and leaves you to manage the delete. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       public &lt;/span&gt;T Receive&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;string &lt;/span&gt;queueName) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: #2b91af"&gt;IMessage
       &lt;/span&gt;{
           InitClient();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = GetOrCreateQueue(queueName);

           &lt;span style="color: blue"&gt;var &lt;/span&gt;queueClient = messagingFactory.CreateQueueClient(queue);

           queueClient.CreateReceiver();

           &lt;span style="color: #2b91af"&gt;BrokeredMessage &lt;/span&gt;brokeredMessage;

           &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;messageReceiver = queueClient.CreateReceiver(&lt;span style="color: #2b91af"&gt;ReceiveMode&lt;/span&gt;.ReceiveAndDelete))
           {
               brokeredMessage = messageReceiver.Receive();
           }

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(brokeredMessage == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               &lt;span style="color: blue"&gt;return default&lt;/span&gt;(T);
           }

           queueClient.Close();
           messagingFactory.Close();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;message = brokeredMessage.GetBody&amp;lt;T&amp;gt;();

           &lt;span style="color: blue"&gt;return &lt;/span&gt;message;
       }&lt;/pre&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;The Demo App&lt;/h3&gt;

&lt;p&gt;I wanted to pull this together and so created an example application which is two console apps one being the client and one being the server. The server sends a message to the client on one queue and when the client receives the message it sends a reply message on another queue. &lt;/p&gt;

&lt;h4&gt;Server&lt;/h4&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    internal class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Welcome to the Queue Demo Server&amp;quot;&lt;/span&gt;);
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Press any key to start:&amp;quot;&lt;/span&gt;);
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();


            &lt;span style="color: blue"&gt;var &lt;/span&gt;serverQueue = &lt;span style="color: #a31515"&gt;&amp;quot;serverqueue&amp;quot;&lt;/span&gt;;
            &lt;span style="color: blue"&gt;var &lt;/span&gt;clientQueue = &lt;span style="color: #a31515"&gt;&amp;quot;clientqueue&amp;quot;&lt;/span&gt;; 

            &lt;span style="color: blue"&gt;var &lt;/span&gt;serviceBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AzureServiceBus&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;IssuerName&amp;quot;&lt;/span&gt;], 
                &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;IssuerKey&amp;quot;&lt;/span&gt;], 
                &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;ServiceNamespace&amp;quot;&lt;/span&gt;]);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;message = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestMessage&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I've travelled along way just to get here.&amp;quot;&lt;/span&gt;);

            
            serviceBus.Send(serverQueue, message);

            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Sent Message:&amp;quot; &lt;/span&gt;+ message.Id + &lt;span style="color: #a31515"&gt;&amp;quot; at &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now);


            &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
            {
                message = serviceBus.Receive&amp;lt;&lt;span style="color: #2b91af"&gt;TestMessage&lt;/span&gt;&amp;gt;(clientQueue);

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(message == &lt;span style="color: blue"&gt;null &lt;/span&gt;|| message.Id == &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;.Empty)
                {
                    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;No messages found yet I'll keep trying&amp;quot;&lt;/span&gt;);
                }
                &lt;span style="color: blue"&gt;else
                &lt;/span&gt;{
                    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Read Message: &amp;quot; &lt;/span&gt;+ message.Id + &lt;span style="color: #a31515"&gt;&amp;quot; at &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now);
                    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(message.Message);
                    &lt;span style="color: blue"&gt;break&lt;/span&gt;;
                }
            }


            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
        }
    }&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;a href="http://lh3.ggpht.com/-WQ0CmoMJcHc/Tgh8b-iTOwI/AAAAAAAAAbk/ds1DUf0gMxE/s1600-h/server_console7.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="server_console" border="0" alt="server_console" src="http://lh4.ggpht.com/-hQ0YhonSIAA/Tgh8cV5WRpI/AAAAAAAAAbo/WGxPCTkUdyU/server_console_thumb2.jpg?imgmax=800" width="626" height="380" /&gt;&lt;/a&gt;&lt;/pre&gt;

&lt;h4&gt;Client&lt;/h4&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   internal class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Program
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;private static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
       {
           &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Welcome to the Queue Demo Client&amp;quot;&lt;/span&gt;);
           &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Press any key to start:&amp;quot;&lt;/span&gt;);
           &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
           
           &lt;span style="color: blue"&gt;var &lt;/span&gt;serverQueue = &lt;span style="color: #a31515"&gt;&amp;quot;serverQueue&amp;quot;&lt;/span&gt;;
           &lt;span style="color: blue"&gt;var &lt;/span&gt;clientQueue = &lt;span style="color: #a31515"&gt;&amp;quot;clientQueue&amp;quot;&lt;/span&gt;; 

           &lt;span style="color: blue"&gt;var &lt;/span&gt;serviceBus = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AzureServiceBus&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;IssuerName&amp;quot;&lt;/span&gt;], 
               &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;IssuerKey&amp;quot;&lt;/span&gt;], 
               &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color: #a31515"&gt;&amp;quot;ServiceNamespace&amp;quot;&lt;/span&gt;]);


           &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)
           {
               &lt;span style="color: blue"&gt;var &lt;/span&gt;message = serviceBus.Receive&amp;lt;&lt;span style="color: #2b91af"&gt;TestMessage&lt;/span&gt;&amp;gt;(serverQueue);

               &lt;span style="color: blue"&gt;if &lt;/span&gt;(message == &lt;span style="color: blue"&gt;null &lt;/span&gt;|| message.Id == &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;.Empty)
               {
                   &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;No messages found yet I'll keep trying&amp;quot;&lt;/span&gt;); 
               }
               &lt;span style="color: blue"&gt;else
               &lt;/span&gt;{
                   &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Read Message: &amp;quot; &lt;/span&gt;+ message.Id + &lt;span style="color: #a31515"&gt;&amp;quot; at &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now);
                   &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(message.Message);
                   &lt;span style="color: blue"&gt;break&lt;/span&gt;;
               }
           }


           &lt;span style="color: blue"&gt;var &lt;/span&gt;responseMessage = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestMessage&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;And so have I&amp;quot;&lt;/span&gt;);

           serviceBus.Send(clientQueue, responseMessage);

           &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Sent Message:&amp;quot; &lt;/span&gt;+ responseMessage.Id + &lt;span style="color: #a31515"&gt;&amp;quot; at &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now);



           &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();
       }
   }&lt;/pre&gt;

&lt;h4&gt;&lt;a href="http://lh5.ggpht.com/-Bg71Vzq4YsU/Tgh8crymHVI/AAAAAAAAAbs/7xXzjyQdnsI/s1600-h/client_console3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="client_console" border="0" alt="client_console" src="http://lh3.ggpht.com/-NG0TW2rEeSg/Tgh8dIAqjdI/AAAAAAAAAbw/kROwanz_Mfk/client_console_thumb1.jpg?imgmax=800" width="618" height="372" /&gt;&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Fiddler&lt;/h4&gt;

&lt;p&gt;If you’re curious you can see what’s going on under the covers using Fiddler. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/-3EN2HfK5juQ/Tgh8dsWJDqI/AAAAAAAAAb0/bz1mVvyoPwA/s1600-h/fiddler3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="fiddler" border="0" alt="fiddler" src="http://lh3.ggpht.com/-KEA5SaoKdvA/Tgh8eDa6WtI/AAAAAAAAAb4/3KViVGYZfLs/fiddler_thumb1.jpg?imgmax=800" width="620" height="130" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;API Change Requests&lt;/h3&gt;

&lt;p&gt;Having played around with the API it’s pretty good and much better than the MessageBuffer API which is really awkward.&lt;/p&gt;

&lt;p&gt;I’d like to see on the &lt;strong&gt;ServiceBusNamespaceClient &lt;/strong&gt;a method that tells you if a Queue exists or not, something like: &lt;/p&gt;

&lt;p&gt;bool QueueExists(string path)&lt;/p&gt;

&lt;p&gt;Currently MessagingFactory, ServiceBusNamespaceClient, QueueClient do not implement interfaces which makes it much harder to Unit Test. Creating an abstracting around these classes would be a big win IMO. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;All in all the Queue API is a much needed and welcomed addition to the Azure offerings and greatly simplifies messaging communication between not always connected clients and the server. It also appears to be very fast as well. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.willbeattie.net.s3.amazonaws.com/AzureQueue.Demo.zip" target="_blank"&gt;Grab the code.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my next post I’m going be looking at the Publish/Subscribe (Topics) features. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/URE2u8Go3D8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/URE2u8Go3D8/windows-azure-appfabric-service-bus.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-vMQAdoTPoEw/Tgh8bv53QDI/AAAAAAAAAbg/2hgBRj5e3pU/s72-c/default_key_thumb1.jpg?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/06/windows-azure-appfabric-service-bus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-7926770658623547216</guid><pubDate>Tue, 21 Jun 2011 14:00:00 +0000</pubDate><atom:updated>2011-06-21T22:00:06.046+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">atdd</category><category domain="http://www.blogger.com/atom/ns#">SpecFlow</category><category domain="http://www.blogger.com/atom/ns#">bdd</category><category domain="http://www.blogger.com/atom/ns#">WatiN</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Getting started with SpecFlow, WatiN, ATDD and BDD</title><description>&lt;p&gt;After completing my Scrum Master course I felt it was high time I review some of our existing engineering practices and consider ways to improve. &lt;/p&gt;  &lt;p&gt;Whilst we practice strict test-first TDD and have 100% code coverage as part of our “definition of done” the one area that we’ve been missing is automated UI testing and acceptance testing. After all, high code coverage doesn’t mean a thing if the requirements are not met. &lt;/p&gt;  &lt;h3&gt;ATDD &amp;amp; BDD&lt;/h3&gt;  &lt;p&gt;This motivated me to rediscover what is known as &lt;a href="http://www.methodsandtools.com/archive/archive.php?id=72" target="_blank"&gt;Acceptance Test Driven Development&lt;/a&gt; or ATDD which is about defining automatable tests from a customer perspective that closely reflect the requirements described in the &lt;a href="http://www.extremeprogramming.org/rules/userstories.html" target="_blank"&gt;User Stories&lt;/a&gt;. This is also associated to &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development" target="_blank"&gt;Behaviour-Driven Development&lt;/a&gt; (BDD).&lt;/p&gt;  &lt;p&gt;The cool kids in the Ruby world caught on to this way back when we were still doing web forms development.&lt;/p&gt;  &lt;p&gt;Some of the Tools available in this space are: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://rspec.info/" target="_blank"&gt;RSpec&lt;/a&gt; (Ruby)     &lt;br /&gt;&lt;a href="http://cukes.info/" target="_blank"&gt;Cucumber&lt;/a&gt; (Ruby)     &lt;br /&gt;&lt;a href="http://code.google.com/p/robotframework/" target="_blank"&gt;Robot Framework&lt;/a&gt; (Java &amp;amp; Python)&amp;#160;&amp;#160; &lt;br /&gt;&lt;a href="http://fitnesse.org/" target="_blank"&gt;FITNESSE&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://watir.com/" target="_blank"&gt;WatiR&lt;/a&gt; Web UI Testing Framework for Ruby&lt;/p&gt;  &lt;p&gt;Of all these tools &amp;amp; frameworks Cucumber is the most interesting in that it allows to describe behavioural tests in plain (non-technical) language allowing to the tests to be authored by the customers or customer proxies. &lt;/p&gt;  &lt;h3&gt;But What About .NET?&lt;/h3&gt;  &lt;p&gt;So I’ve mentioned a couple of the leading tools and frameworks in this area which are available in the Java and dynamic language world. In the .NET world there are a number of frameworks around which are either inspired by or ports of their counterparts. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://nspec.org/" target="_blank"&gt;NSpec&lt;/a&gt; (Inspired by RSpec)     &lt;br /&gt;&lt;a href="http://www.specflow.org/" target="_blank"&gt;SpecFlow&lt;/a&gt; (Inspired by Cucumber and conforms to Gherkin syntax)     &lt;br /&gt;&lt;a href="http://watin.org/" target="_blank"&gt;WatiN&lt;/a&gt; (Inspired by WatiR)&lt;/p&gt;  &lt;p&gt;NSpec and RSpec focus on BDD style Unit-Testing where as Cucumber and SpecFlow are more suited to acceptance tests. &lt;/p&gt;  &lt;p&gt;For that reason I’m going to be looking at SpecFlow and WatiN for the remained of this post. &lt;/p&gt;  &lt;h3&gt;SpecFlow&lt;/h3&gt;  &lt;p&gt;For those of you without any knowledge of Cucumber or SpecFlow essentially how it works is that you specify Features which are files in your project.    &lt;br /&gt;Features firstly define the requirement from a customers perspective using non-techie vocabulary and then specify the scenarios or steps using the Given, When, Then words. &lt;/p&gt;  &lt;p&gt;Here is a simple example of a how a feature can be written (I’m not an expert on this language yet). &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Feature&lt;/span&gt;: Authentication
    In order to allow site personalization
    As a user
    I want to be able to login 

&lt;span style="color: blue"&gt;Scenario&lt;/span&gt;: Navigation to Home 
    &lt;span style="color: blue"&gt;When &lt;/span&gt;I navigate to /Home/Index 
    &lt;span style="color: blue"&gt;Then &lt;/span&gt;I should be on the home page

&lt;span style="color: blue"&gt;Scenario&lt;/span&gt;: Logging in
    &lt;span style="color: blue"&gt;Given &lt;/span&gt;I am on the home page
    &lt;span style="color: blue"&gt;And &lt;/span&gt;I have entered will into the username field
    &lt;span style="color: blue"&gt;And &lt;/span&gt;I have entered test into the password field 
    &lt;span style="color: blue"&gt;When &lt;/span&gt;I press submit
    &lt;span style="color: blue"&gt;Then &lt;/span&gt;the result should be a Logged In title on the screen &lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Relating this back to Agile you can think of a feature as a user story.&amp;#160; &lt;br /&gt;

  &lt;br /&gt;It should be noted that developers should not be writing these, they should be written by either the customer or a customer proxy such as a tester or business analyst. If these are written by non-technical people then you can ensure that they are focusing on the requirement and not the technical implementation. &lt;/p&gt;

&lt;h3&gt;Setting up the Test Project&lt;/h3&gt;

&lt;p&gt;After downloading and installing &lt;a href="http://www.specflow.org/downloads/installer.aspx" target="_blank"&gt;SpecFlow&lt;/a&gt; (make sure to close Visual Studio when doing so) you’ll need to create a standard Unit Test project. e.g. SpecFlowDemo.AcceptanceTests. &lt;/p&gt;

&lt;p&gt;Add a reference to TechTalk.SpecFlow.dll which you can find in C:\Program Files\TechTalk\SpecFlow.&lt;/p&gt;

&lt;p&gt;If you’re using MSTest then you’ll need to add the following to your App.Config &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;section &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;specFlow&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;specFlow&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;unitTestProvider &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MsTest&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;specFlow&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;I like to create a separate folder for the Features and Steps. &lt;/p&gt;

&lt;p&gt;At this point your project should be looking something like. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/-QdAoFUOIL_E/TfwbGUuvYuI/AAAAAAAAAa8/FVTUJwVY16M/s1600-h/project4.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="project" border="0" alt="project" src="http://lh6.ggpht.com/-kZ8ibK29hp0/TfwbG0saU3I/AAAAAAAAAbA/ykqO2cjFJjA/project_thumb2.jpg?imgmax=800" width="408" height="204" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Defining a Feature&lt;/h3&gt;

&lt;p&gt;As I mentioned earlier a feature should try and map to a single user story. &lt;/p&gt;

&lt;p&gt;For this example I’m going to create a Search feature which searches google for BDD related articles.&lt;/p&gt;

&lt;p&gt;Add New Item &amp;gt; SpecFlow Feature File &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/-rPlRnYADtqU/TfwbHjbsfOI/AAAAAAAAAbE/EShN9ZMXaNk/s1600-h/addnewitem_search_feature4.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="addnewitem_search_feature" border="0" alt="addnewitem_search_feature" src="http://lh4.ggpht.com/-hB3gY9Krtjw/TfwbIN-TIsI/AAAAAAAAAbI/cTqeGJEcgFQ/addnewitem_search_feature_thumb2.jpg?imgmax=800" width="629" height="460" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will add a Feature file which comprises of the .feature part and the .cs code-behind. Make sure you don’t touch the .cs file as this contains designer generated code. &lt;/p&gt;

&lt;h4&gt;The Feature&lt;/h4&gt;

&lt;p&gt;For this fictitious example I’m going to use a Search feature. This is described below using the Gherkin language.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Feature&lt;/span&gt;: Search
    In order to find articles on BDD
    As a BDD fanatic 
    I want to enter a keyword into a search engine and be shown a list of related websites


&lt;span style="color: blue"&gt;Scenario&lt;/span&gt;: Navigate to Search Engine
    &lt;span style="color: blue"&gt;When &lt;/span&gt;I enter http://www.google.com in the address bar
    &lt;span style="color: blue"&gt;Then &lt;/span&gt;I should be on the home page


&lt;span style="color: blue"&gt;Scenario&lt;/span&gt;: Perform search
    &lt;span style="color: blue"&gt;Given &lt;/span&gt;I am on the home page
    &lt;span style="color: blue"&gt;And &lt;/span&gt;I have entered BDD into the keyword textbox
    &lt;span style="color: blue"&gt;When &lt;/span&gt;I press the btnG button
    &lt;span style="color: blue"&gt;Then &lt;/span&gt;I should see a list of articles related to BDD &lt;/pre&gt;

&lt;h3&gt;Adding the Steps&lt;/h3&gt;

&lt;p&gt;Now we are going to add a Step definition for each of the scenarios described in the Feature file. &lt;/p&gt;

&lt;p&gt;Right Click on Project &amp;gt; Add New Item &amp;gt; SpecFlow Step Defintion&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/-LXbQQM5yzPg/TfwbIv40oQI/AAAAAAAAAbM/YoV0tu91eS8/s1600-h/addnewitem_step_definition5.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="addnewitem_step_definition" border="0" alt="addnewitem_step_definition" src="http://lh5.ggpht.com/-MdoO6ozjOjQ/TfwbJqrCCfI/AAAAAAAAAbQ/kODbwB0qVGQ/addnewitem_step_definition_thumb3.jpg?imgmax=800" width="637" height="465" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve added the Step you have to add the methods for each of the Given, When, Then lines in your scenario and annotate them with the correct attribute.&lt;/p&gt;

&lt;p&gt;The key thing here is that the class needs to be annotated with the &lt;strong&gt;Binding&lt;/strong&gt; attribute. &lt;/p&gt;

&lt;p&gt;You can use the &lt;strong&gt;(.*) &lt;/strong&gt;expression to represent variables coming from your Feature file.&amp;#160; &lt;/p&gt;

&lt;h4&gt;NavigateToSearchEngine Step &lt;/h4&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;]
 &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NavigateToSearchEngine
 &lt;/span&gt;{
     [&lt;span style="color: #2b91af"&gt;When&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I enter (.*) in the address bar&amp;quot;&lt;/span&gt;)]
     &lt;span style="color: blue"&gt;public void &lt;/span&gt;when_i_enter_the_url(&lt;span style="color: blue"&gt;string &lt;/span&gt;url)
     {
     }

     [&lt;span style="color: #2b91af"&gt;Then&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I should be on the home page&amp;quot;&lt;/span&gt;)]
     &lt;span style="color: blue"&gt;public void &lt;/span&gt;then_i_should_be_on_the_home_page()
     {
     }
 }&lt;/pre&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;h4&gt;PerformSearch Step &lt;/h4&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PerformSearch
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;Given&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I am on the home page&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;given_i_am_on_the_home_page()
        {
           
        }

        [&lt;span style="color: #2b91af"&gt;Given&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I have entered (.*) into the keyword textbox&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;and_i_have_entered(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
        {

        }

       [&lt;span style="color: #2b91af"&gt;When&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I press the (.*) button&amp;quot;&lt;/span&gt;)]
       &lt;span style="color: blue"&gt;public void &lt;/span&gt;when_i_press_the_button(&lt;span style="color: blue"&gt;string &lt;/span&gt;button)
       {

       }
    }&lt;/pre&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;WatiN&lt;/h3&gt;

&lt;p&gt;Now that we have our Feature and Steps defined in order to execute the UI tests we’re going to need WatiN. For more info on WatiN check out the &lt;a href="http://watin.org/documentation/" target="_blank"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Download &lt;a href="http://sourceforge.net/projects/watin/files/WatiN%202.x/" target="_blank"&gt;WatiN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add references to Waitn.Core.dll &amp;amp; Interop.SHDocVw.dll which can be found in C:\Program Files\WatiN Test Recorder&lt;/p&gt;

&lt;p&gt;Ensure that Interop.SHDocVw has &lt;strong&gt;Embed Interop Types&lt;/strong&gt; set to False&lt;/p&gt;

&lt;h4&gt;Static Browser Class&lt;/h4&gt;

&lt;p&gt;This class is a static helper class for accessing the browser. WatiN has support for Internet Explorer &amp;amp; Firefox but I haven’t been able to get it to work with Firefox 4 I just tend to use the IE implementation.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#region

using &lt;/span&gt;TechTalk.SpecFlow;
&lt;span style="color: blue"&gt;using &lt;/span&gt;WatiN.Core;

&lt;span style="color: blue"&gt;#endregion

namespace &lt;/span&gt;SpecFlowDemo.AcceptanceTests
{
    [&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebBrowser
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Browser &lt;/span&gt;Current
        {
            &lt;span style="color: blue"&gt;get
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: #2b91af"&gt;ScenarioContext&lt;/span&gt;.Current.ContainsKey(&lt;span style="color: #a31515"&gt;&amp;quot;browser&amp;quot;&lt;/span&gt;))
                {
                    &lt;span style="color: #2b91af"&gt;ScenarioContext&lt;/span&gt;.Current[&lt;span style="color: #a31515"&gt;&amp;quot;browser&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IE&lt;/span&gt;();
                }
                &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Browser&lt;/span&gt;) &lt;span style="color: #2b91af"&gt;ScenarioContext&lt;/span&gt;.Current[&lt;span style="color: #a31515"&gt;&amp;quot;browser&amp;quot;&lt;/span&gt;];
            }
        }

        [&lt;span style="color: #2b91af"&gt;AfterScenario&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public static void &lt;/span&gt;Close()
        {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ScenarioContext&lt;/span&gt;.Current.ContainsKey(&lt;span style="color: #a31515"&gt;&amp;quot;browser&amp;quot;&lt;/span&gt;))
            {
                Current.Close();
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Implementing the Steps&lt;/h3&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;h4&gt;NavigateToSearchEngine&lt;/h4&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NavigateToSearchEngine
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;When&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I enter (.*) in the address bar&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;when_i_enter_the_url(&lt;span style="color: blue"&gt;string &lt;/span&gt;url)
        {
            &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.GoTo(url);
        }

        [&lt;span style="color: #2b91af"&gt;Then&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I should be on the home page&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;then_i_should_be_on_the_home_page()
        {
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.Title, &lt;span style="color: #a31515"&gt;&amp;quot;Google&amp;quot;&lt;/span&gt;);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.TextFields.Exists(tf =&amp;gt; tf.Name == &lt;span style="color: #a31515"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;));
        }
    }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;PerformSearch&lt;/h4&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PerformSearch
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;Given&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I am on the home page&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;given_i_am_on_the_home_page()
        {
            &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.GoTo(&lt;span style="color: #a31515"&gt;&amp;quot;http://www.google.com&amp;quot;&lt;/span&gt;);
        }

       
        [&lt;span style="color: #2b91af"&gt;Given&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I have entered (.*) into the keyword textbox&amp;quot;&lt;/span&gt;)]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;and_i_have_entered(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;field = &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.TextField(tf =&amp;gt; tf.Name == &lt;span style="color: #a31515"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;);
            
            field.TypeText(keyword);

        }

       [&lt;span style="color: #2b91af"&gt;When&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I press the (.*) button&amp;quot;&lt;/span&gt;)]
       &lt;span style="color: blue"&gt;public void &lt;/span&gt;when_i_press_the_button(&lt;span style="color: blue"&gt;string &lt;/span&gt;buttonName)
       {
           &lt;span style="color: blue"&gt;var &lt;/span&gt;button = &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.Button(b =&amp;gt; b.Name == buttonName);

           button.Click();
           
           &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.WaitForComplete(); 

       }

       [&lt;span style="color: #2b91af"&gt;Then&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;I should see a list of articles related to (.*)&amp;quot;&lt;/span&gt;)]
       &lt;span style="color: blue"&gt;public void &lt;/span&gt;then_i_should_see_a_list_articles_related_to(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
       {
           &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.WaitUntilContainsText(&lt;span style="color: #a31515"&gt;&amp;quot;Advanced search&amp;quot;&lt;/span&gt;);
           
           &lt;span style="color: blue"&gt;var &lt;/span&gt;searchDiv = &lt;span style="color: #2b91af"&gt;WebBrowser&lt;/span&gt;.Current.Div(&lt;span style="color: #a31515"&gt;&amp;quot;res&amp;quot;&lt;/span&gt;);

           &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(searchDiv.Children().Count == 3); 
           
       }
    }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Running the Tests&lt;/h3&gt;

&lt;p&gt;Now you’re ready to run the tests and with a bit of luck they should both pass. You will notice during the tests that Internet Explorer will open and you can actually watch the UI test happen.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/-w3eJXHfAKN0/TfwbKPQxeQI/AAAAAAAAAbU/81dK37wGWgk/s1600-h/test_results%25255B1%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="test_results" border="0" alt="test_results" src="http://lh6.ggpht.com/-230_zYCEJao/TfwbK77CrlI/AAAAAAAAAbY/L-RvINYoNGc/test_results_thumb.jpg?imgmax=800" width="506" height="113" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Console Output&lt;/h4&gt;

&lt;p&gt;You get a nice descriptive console output as well which is nice. &lt;/p&gt;

&lt;p&gt;When I enter &lt;a href="http://www.google.com"&gt;http://www.google.com&lt;/a&gt; in the address bar 

  &lt;br /&gt;-&amp;gt; done: NavigateToSearchEngine.when_i_enter_the_url(&amp;quot;&lt;a href="http://www.google...&amp;quot;)"&gt;http://www.google...&amp;quot;)&lt;/a&gt; (15.5s) 

  &lt;br /&gt;Then I should be on the home page 

  &lt;br /&gt;-&amp;gt; done: NavigateToSearchEngine.then_i_should_be_on_the_home_page() (2.9s)&lt;/p&gt;

&lt;p&gt;Given I am on the home page 
  &lt;br /&gt;-&amp;gt; done: PerformSearch.given_i_am_on_the_home_page() (6.4s) 

  &lt;br /&gt;And I have entered BDD into the keyword textbox 

  &lt;br /&gt;-&amp;gt; done: PerformSearch.and_i_have_entered(&amp;quot;BDD&amp;quot;) (3.2s) 

  &lt;br /&gt;When I press the btnG button 

  &lt;br /&gt;-&amp;gt; done: PerformSearch.when_i_press_the_button(&amp;quot;btnG&amp;quot;) (0.3s) 

  &lt;br /&gt;Then I should see a list of articles related to BDD 

  &lt;br /&gt;-&amp;gt; done: PerformSearch.then_i_should_see_a_list_articles_related_to(&amp;quot;BDD&amp;quot;) (1.4s)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;The Code&lt;/h3&gt;

&lt;p&gt;You can download the code &lt;a href="http://blog.willbeattie.net.s3.amazonaws.com/SpecFlow_Demo.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;If you’re not doing ATDD or Automated UI Testing then I strongly urge you to consider SpecFlow and WaitN which can add huge value to your testing process. I’m really looking forward to expanding our definition of done to include these. &lt;/p&gt;

&lt;p&gt;There is also a &lt;a href="http://watintestrecord.sourceforge.net/" target="_blank"&gt;WatiN Test Recorder&lt;/a&gt; which can assist in automating some of your tests or at the least show you the capability of WatiN. At last look though it doesn’t seem to be an active project anymore. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/lwY9kTzoJ4o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/lwY9kTzoJ4o/getting-started-with-specflow-watin.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-kZ8ibK29hp0/TfwbG0saU3I/AAAAAAAAAbA/ykqO2cjFJjA/s72-c/project_thumb2.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/06/getting-started-with-specflow-watin.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-3592102630660273346</guid><pubDate>Tue, 14 Jun 2011 14:00:00 +0000</pubDate><atom:updated>2011-06-14T22:00:06.322+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">video</category><category domain="http://www.blogger.com/atom/ns#">html5</category><title>IE Security Warning with QuickTime Object tags</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I just received a bug report about the infamous Internet Explorer Security Warning for one of the pages in our application that serves video content over HTTPS.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-1eOuND25_GY/TfHA8CMKs4I/AAAAAAAAAps/YZmfEkabRjA/s1600-h/iesecuritywarning%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="iesecuritywarning" border="0" alt="iesecuritywarning" src="http://lh6.ggpht.com/-a-rUVOnkXmY/TfHA9KNEYrI/AAAAAAAAApw/ZtBtYBvgUEc/iesecuritywarning_thumb%25255B1%25255D.png?imgmax=800" width="560" height="229"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;After viewing the source I found the offender which turned out to be the &lt;strong&gt;codebase&lt;/strong&gt; attribute set to &lt;a href="http://www.apple.com/qtactivex/qtplugin.cab"&gt;http://www.apple.com/qtactivex/qtplugin.cab&lt;/a&gt;.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;object &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;="videoObject" &lt;/span&gt;&lt;span style="color: red"&gt;classid&lt;/span&gt;&lt;span style="color: blue"&gt;="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" 
            &lt;/span&gt;&lt;span style="color: red"&gt;codebase&lt;/span&gt;&lt;span style="color: blue"&gt;="http://www.apple.com/qtactivex/qtplugin.cab" 
            &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;="330" &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;="292"&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="src" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="https://securedomain/video.mp4" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="controller" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="autoplay" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="False" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="scale" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="aspect" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="cache" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="saveembedtags" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="postdomevents" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt; 
               
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--[if IE] --&amp;gt; 
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;EMBED &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="movie"
                &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;="292"
                &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;="330"
                &lt;/span&gt;&lt;span style="color: red"&gt;scale&lt;/span&gt;&lt;span style="color: blue"&gt;="aspect"
                &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="https://securedomain/video.mp4"
                &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="video/quicktime"
                &lt;/span&gt;&lt;span style="color: red"&gt;pluginspage&lt;/span&gt;&lt;span style="color: blue"&gt;="www.apple.com/quicktime/download"
                &lt;/span&gt;&lt;span style="color: red"&gt;controller&lt;/span&gt;&lt;span style="color: blue"&gt;="true"
                &lt;/span&gt;&lt;span style="color: red"&gt;autoplay&lt;/span&gt;&lt;span style="color: blue"&gt;="False"
            /&amp;gt; 
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--[endif]--&amp;gt; 
        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;object&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The fix was just to change this to https. &lt;a href="https://www.apple.com/qtactivex/qtplugin.cab"&gt;https://www.apple.com/qtactivex/qtplugin.cab&lt;/a&gt;. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;object &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;="videoObject" &lt;/span&gt;&lt;span style="color: red"&gt;classid&lt;/span&gt;&lt;span style="color: blue"&gt;="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" 
            &lt;/span&gt;&lt;span style="color: red"&gt;codebase&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;strong&gt;https://www.apple.com/qtactivex/qtplugin.cab&lt;/strong&gt;" 
            &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;="330" &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;="292"&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="src" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="https://securedomain/video.mp4" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="controller" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="autoplay" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="False" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="scale" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="aspect" /&amp;gt; 
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="cache" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="saveembedtags" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="postdomevents" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;="true"/&amp;gt; 
               
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--[if IE] --&amp;gt; 
            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;EMBED &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;="movie"
                &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;="292"
                &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;="330"
                &lt;/span&gt;&lt;span style="color: red"&gt;scale&lt;/span&gt;&lt;span style="color: blue"&gt;="aspect"
                &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="https://securedomain/video.mp4"
                &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="video/quicktime"
                &lt;/span&gt;&lt;span style="color: red"&gt;pluginspage&lt;/span&gt;&lt;span style="color: blue"&gt;="www.apple.com/quicktime/download"
                &lt;/span&gt;&lt;span style="color: red"&gt;controller&lt;/span&gt;&lt;span style="color: blue"&gt;="true"
                &lt;/span&gt;&lt;span style="color: red"&gt;autoplay&lt;/span&gt;&lt;span style="color: blue"&gt;="False"
            /&amp;gt; 
            &lt;/span&gt;&lt;span style="color: #006400"&gt;&amp;lt;!--[endif]--&amp;gt; 
        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;object&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Fortunately our users have the option of choosing the &lt;a href="http://blog.willbeattie.net/2010/05/html5-video-tag-codec-support.html"&gt;HTML5 Video&lt;/a&gt; player meaning they don’t need to install any 3rd party plugins to view videos. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/8V0QjDf0Aeo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/8V0QjDf0Aeo/ie-security-warning-with-quicktime.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-a-rUVOnkXmY/TfHA9KNEYrI/AAAAAAAAApw/ZtBtYBvgUEc/s72-c/iesecuritywarning_thumb%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/06/ie-security-warning-with-quicktime.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-4211295716520323801</guid><pubDate>Tue, 17 May 2011 14:00:00 +0000</pubDate><atom:updated>2011-05-17T22:00:07.016+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">ec2</category><category domain="http://www.blogger.com/atom/ns#">.net 4</category><title>Entity Framework 4 with Amazon RDS</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In my &lt;a href="http://blog.willbeattie.net/2011/05/using-entity-framework-4-with-mysql.html" target="_blank"&gt;last post&lt;/a&gt; I demonstrated how you can use MySQL with Entity Framework 4. &lt;/p&gt;  &lt;p&gt;In this post I’m going to show you how to use &lt;a href="http://aws.amazon.com/rds/" target="_blank"&gt;Amazon RDS&lt;/a&gt;. Amazon RDS is a Relational Database Service which is similar to &lt;a href="http://www.microsoft.com/windowsazure/sqlazure/" target="_blank"&gt;SQL Azure&lt;/a&gt; except that it supports MySQL &amp;amp; Oracle is coming soon. This is the actually the first time I’ve attempted to use the service and am going to be writing this as I go.&amp;#160; &lt;/p&gt;  &lt;p&gt;Amazon RDS takes care of all the critical database management tasks like software updates, backups &amp;amp; replication.&lt;/p&gt;  &lt;h3&gt;Signing Up&lt;/h3&gt;  &lt;p&gt;This post assumes you already have an AWS (Amazon Web Services) account, if you don’t go to the &lt;a href="https://www.amazon.com/ap/signin?_encoding=UTF8&amp;amp;openid.assoc_handle=aws&amp;amp;openid.return_to=https%3A%2F%2Faws-portal.amazon.com%2Fgp%2Faws%2Fdeveloper%2Fregistration%2Findex.html&amp;amp;openid.mode=checkid_setup&amp;amp;openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&amp;amp;openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&amp;amp;openid.pape.max_auth_age=600&amp;amp;siteState=awsMode%3A%3AsignUp%3A%3A&amp;amp;pageId=aws.ssop&amp;amp;openid.pape.preferred_auth_policies=http%3A%2F%2Fschemas.openid.net%2Fpape%2Fpolicies%2F2007%2F06%2Fmulti-factor-physical&amp;amp;marketplaceId=ATVPDKIKX0DER&amp;amp;accountStatusPolicy=P1&amp;amp;openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&amp;amp;openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&amp;amp;authCookies=1" target="_blank"&gt;Sign In&lt;/a&gt; page. &lt;/p&gt;  &lt;p&gt;As with all Amazon Web Services you have to explicitly sign up, you can do this by going to &lt;a title="http://aws.amazon.com/rds/" href="http://aws.amazon.com/rds/"&gt;http://aws.amazon.com/rds/&lt;/a&gt; and clicking the “Sign Up For Amazon RDS” button. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;Signing up is not instant, it took about 12 hours for me to receive the confirmation email. &lt;/p&gt;  &lt;h3&gt;Launching the DB Instance&lt;/h3&gt;  &lt;p&gt;Log into the &lt;a href="https://console.aws.amazon.com/" target="_blank"&gt;AWS console&lt;/a&gt; and go to the Amazon RDS tab. &lt;/p&gt;  &lt;h4&gt;Step 1 – Launch DB Instance&lt;/h4&gt;  &lt;p&gt;Click on the big Launch DB Instance button. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/Tc4XSX-xSpI/AAAAAAAAAZ8/MX5-K4DrbtU/s1600-h/launchdb%5B7%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="launchdb" border="0" alt="launchdb" src="http://lh4.ggpht.com/_la3Rv-0jOCI/Tc4XTd9QqiI/AAAAAAAAAaA/9VFlgcXnQ88/launchdb_thumb%5B5%5D.jpg?imgmax=800" width="696" height="363" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Step 2 – DB Instance Details&lt;/h4&gt;  &lt;p&gt;After clicking the Launch DB button you will get the below screen. &lt;/p&gt;  &lt;p&gt;For information on the DB Instance Class go to the &lt;a href="http://aws.amazon.com/rds/#pricing" target="_blank"&gt;AWS RDS page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Multi-AZ Deployment is the ability to have the DB instance replicated in another availability zone with Amazon managing the failover, we’re not going to worry about that for now. This can be changed at anytime after the instance is created.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/Tc4XTwKwZxI/AAAAAAAAAaE/zA_dhSOJZ5A/s1600-h/launchdb_step1%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="launchdb_step1" border="0" alt="launchdb_step1" src="http://lh4.ggpht.com/_la3Rv-0jOCI/Tc4XUnaHzBI/AAAAAAAAAaI/YYWT8Ol4UHI/launchdb_step1_thumb%5B2%5D.jpg?imgmax=800" width="694" height="571" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; See the maximum size of 1024 GB, compared with SQL Azures offering of 50GB.&amp;#160; &lt;/p&gt;  &lt;h4&gt;Step 3 – Additional Configuration&lt;/h4&gt;  &lt;p&gt;On this screen you can specify the Database name, port &amp;amp; availability zone. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/Tc4XVGO7tKI/AAAAAAAAAaM/d2WRVmzEfY4/s1600-h/launch_db_step2%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="launch_db_step2" border="0" alt="launch_db_step2" src="http://lh3.ggpht.com/_la3Rv-0jOCI/Tc4XV8BpTzI/AAAAAAAAAaQ/PM2zXjGHfCk/launch_db_step2_thumb%5B2%5D.jpg?imgmax=800" width="704" height="485" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Step 4 – Management Options&lt;/h4&gt;  &lt;p&gt;On this screen you set your preferences for DB backups and maintenance. You’ll want to tweak this depending on where your customers are geographically located.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/Tc4XWTk1WtI/AAAAAAAAAaU/P5QHHfNgVB8/s1600-h/launch_db_step3%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="launch_db_step3" border="0" alt="launch_db_step3" src="http://lh4.ggpht.com/_la3Rv-0jOCI/Tc4XXfcUpSI/AAAAAAAAAaY/8qljzVmsjLg/launch_db_step3_thumb%5B2%5D.jpg?imgmax=800" width="709" height="533" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Step 5 – Review&lt;/h4&gt;  &lt;p&gt;Finally you can review all of your settings and when you’re satisfied click the Launch DB Instance and let Amazon work their magic. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/Tc4XX0DngMI/AAAAAAAAAac/sdMV8BSVhbs/s1600-h/launch_db_step_4%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="launch_db_step_4" border="0" alt="launch_db_step_4" src="http://lh4.ggpht.com/_la3Rv-0jOCI/Tc4X4rpL4UI/AAAAAAAAAag/m6dfNBNgQtY/launch_db_step_4_thumb%5B2%5D.jpg?imgmax=800" width="712" height="606" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Done&lt;/h4&gt;  &lt;p&gt;After a about 5 minutes or so the instance will be available in the DB Instances page. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/Tc4X5KZS41I/AAAAAAAAAak/2WpP6xb3kdA/s1600-h/DBInstances%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DBInstances" border="0" alt="DBInstances" src="http://lh6.ggpht.com/_la3Rv-0jOCI/Tc4X5-xE31I/AAAAAAAAAao/AtF8zZxwwvs/DBInstances_thumb%5B3%5D.jpg?imgmax=800" width="718" height="243" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Security&lt;/h3&gt;  &lt;p&gt;Now that we’ve created our instance we need to set some security rules in order to be able to access it from EC2 instances and any other external machines. I’m going to add a rule to allow access from machine so that I can do the data &amp;amp; schema import. &lt;/p&gt;  &lt;p&gt;You can either choose from CIDR/IP or EC2 Security Group when setting your rule. When selecting the EC2 Security Group you write the name of the security group used in EC2. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/Tc4X6UFiRhI/AAAAAAAAAas/greGhLvcZVM/s1600-h/security_groups%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="security_groups" border="0" alt="security_groups" src="http://lh5.ggpht.com/_la3Rv-0jOCI/Tc4Y6EvqrYI/AAAAAAAAAaw/d-vDMbxVO98/security_groups_thumb%5B3%5D.jpg?imgmax=800" width="714" height="360" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For more information on security groups go to &lt;a href="http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/index.html?USER_WorkingWithSecurityGroups.html" target="_blank"&gt;Working with DB Security Groups&lt;/a&gt;. &lt;/p&gt;  &lt;h3&gt;Importing the Data &amp;amp; Schema&lt;/h3&gt;  &lt;p&gt;The preferred method for importing schema and data into your DB Instance for datasets of 1GB and less is to extract the data with &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html" target="_blank"&gt;mysqldump&lt;/a&gt; and pipe it directly to your instance. If you dataset is larger than 1GB checkout the &lt;a href="http://aws.amazon.com/articles/2933?_encoding=UTF8&amp;amp;jiveRedirect=1" target="_blank"&gt;Amazon RDS Customer Data Import Guide for MySQL&lt;/a&gt;. &lt;/p&gt;  &lt;h4&gt;Connection&lt;/h4&gt;  &lt;p&gt;First you need to get the Endpoint for the instance from the AWS console. This can be found be going to the DB Instances page and clicking on your DB Instance.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/Tc4Y6xpYZ6I/AAAAAAAAAa0/4eJBq0_fkUo/s1600-h/endpoint%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="endpoint" border="0" alt="endpoint" src="http://lh3.ggpht.com/_la3Rv-0jOCI/Tc4Y7nuCYiI/AAAAAAAAAa4/LfsHPy21_wg/endpoint_thumb%5B2%5D.jpg?imgmax=800" width="711" height="362" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Before starting you’ll want to check that you can connect to the instance properly using telnet: &lt;/p&gt;  &lt;p&gt;telnet efdemo.cauwsk2cfjqz.ap-southeast-1.rds.amazonaws.com 3306&lt;/p&gt;  &lt;p&gt;If you experience any problems here then check your security group rules and local firewall settings. &lt;/p&gt;  &lt;h4&gt;Import&lt;/h4&gt;  &lt;p&gt;Here is the command for the import:&lt;/p&gt;  &lt;p&gt;&amp;quot;C:\Program Files\MySQL\MySQL Server 5.1\bin\&amp;quot;\mysqldump efdemo --host=efdemo.cauwsk2cfjqz.ap-southeast-1.rds.amazonaws.com --port 3306 --user=willbt --password&lt;/p&gt;  &lt;p&gt;If everything went to plan you should get the “Dump completed” message in the command prompt and we’re ready to test the connectivity from EC2. &lt;/p&gt;  &lt;p&gt;If you have issues, make sure the version of your DB Instance and local MySQL Installation are the same. &lt;/p&gt;  &lt;p&gt;Of course you could also just connect to your instance using MySQL Administrator &amp;amp; MySQL Query Browser. &lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Accessing from EC2&lt;/h3&gt;  &lt;p&gt;Once you’ve got your instance setup in EC2 you can deploy your application to it. &lt;/p&gt;  &lt;p&gt;If you’ve added the same security group that your EC2 instance uses to the DB Instance security groups then you should have no problems connecting to your DB Instance. Make sure the port you specified when creating the DB Instance is configured in any firewall rules. &lt;/p&gt;  &lt;p&gt;To double check go onto your EC2 instance and run the telnet command again, if you have any issues check the instance firewall rules and the security group settings again. &lt;/p&gt;  &lt;p&gt;You will need to also install the &lt;a href="http://dev.mysql.com/downloads/connector/net/" target="_blank"&gt;MySQL Connector&lt;/a&gt; onto your EC2 instance or make sure you set Copy To Local on the assemblies MySql.Data and MySql.Data.Entity. &lt;/p&gt;  &lt;p&gt;Finally the connection string by setting the &lt;em&gt;&lt;strong&gt;server &lt;/strong&gt;&lt;/em&gt;attribute to the Endpoint of your DB Instance. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;EFDemoEntities&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;metadata=res://*/EFDemo.csdl|res://*/EFDemo.ssdl|res://*/EFDemo.msl;provider=MySql.Data.MySqlClient;provider connection string=&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;server=&lt;strong&gt;efdemo.cauwsk2cfjqz.ap-southeast-1.rds.amazonaws.com&lt;/strong&gt;;User Id=willbt;Password=password;database=efdemo;Persist Security Info=True&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;quot;&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;providerName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;System.Data.EntityClient&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Pricing &lt;/h3&gt;

&lt;p&gt;When you compare the pricing between a MySQL solution and the SQL Server solution it’s very easy to see benefits of going MySQL. &lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="376"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="187"&gt;&amp;#160;&lt;/td&gt;

      &lt;td valign="top" width="96"&gt;&lt;strong&gt;Annual USD&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="91"&gt;&lt;strong&gt;Monthly USD&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="185"&gt;My SQL RDS (Large)&lt;/td&gt;

      &lt;td valign="top" width="98"&gt;
        &lt;p align="right"&gt;$ 3854.40&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="93"&gt;
        &lt;p align="right"&gt;$ 321.20&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="183"&gt;SQL Server Standard (Large)&lt;/td&gt;

      &lt;td valign="top" width="99"&gt;
        &lt;p align="right"&gt;$ 9460.80&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="95"&gt;
        &lt;p align="right"&gt;$ 788.40&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;p&gt;That’s a pretty big difference &amp;amp; also bear in mind that with a SQL Server solution you’re not going to get automated backups, updates &amp;amp; failover. &lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Writing this blog was my first experience with Amazon RDS and I have to say I am very impressed with just how easy it is to get setup. &lt;/p&gt;

&lt;p&gt;Amazon EC2 &amp;amp; RDS with MySQL for .NET applications is a very attractive deployment option and the next greenfield project I work on I’ll be seriously considering Amazon RDS with MySQL. &lt;/p&gt;

&lt;p&gt;I’ve got a few pet projects kicking around with would be well suited for this platform so stay tuned. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/RsK4IXqcIl8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/RsK4IXqcIl8/entity-framework-4-with-amazon-rds.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_la3Rv-0jOCI/Tc4XTd9QqiI/AAAAAAAAAaA/9VFlgcXnQ88/s72-c/launchdb_thumb%5B5%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/05/entity-framework-4-with-amazon-rds.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-7289179396194574534</guid><pubDate>Tue, 10 May 2011 12:00:00 +0000</pubDate><atom:updated>2011-05-10T20:00:12.720+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">entity framework</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">.net 4</category><title>Using Entity Framework 4 with MySQL</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If you’re on the .NET Platform then MS SQL Server is usually the de-facto choice for the RDBMS. However if you’re at all cost conscience then you will realize that scaling and replication is going to cost you a fair chunk of change in licensing fees. &lt;/p&gt; &lt;p&gt;For that reason open source RDBMSs and in particular MySQL offer a much cheaper alternative. &lt;/p&gt; &lt;p&gt;In this post I’d like to demonstrate how you can use &lt;a href="http://msdn.microsoft.com/en-us/data/aa937723" target="_blank"&gt;Entity Framework 4&lt;/a&gt; with MySQL.&lt;/p&gt; &lt;h3&gt;MySQL Connector Net 6.3.6&lt;/h3&gt; &lt;p&gt;The first thing you’ll need to do is download and install the latest version of the MySQL Connector for .NET from &lt;a href="http://dev.mysql.com/downloads/connector/net/"&gt;http://dev.mysql.com/downloads/connector/net/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Make sure that Visual Studio is closed when you install. &lt;/p&gt; &lt;h3&gt;Pascal Case Table Names&lt;/h3&gt; &lt;p&gt;Because we are going to generate our Entity Framework Model of an existing database we want to make sure that the entity names use pascal casing. By default MySQL on Windows forces lowercase table names. &lt;/p&gt; &lt;p&gt;You can change this behaviour by adding &lt;strong&gt;&lt;em&gt;lower_case_table_names=2&lt;/em&gt;&lt;/strong&gt; to your my.ini file which will located in &lt;br&gt;C:\Program Files\MySQL\MySQL Server &amp;lt;YOURVERSION&amp;gt;\&lt;/p&gt; &lt;p&gt;Read more about Identifier case sensitivity on the &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/identifier-case-sensitivity.html" target="_blank"&gt;MySQL site&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;NOTE: &lt;/strong&gt;This will need to be done before you create your Schema and Tables. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Creating the Entity Framework Model&lt;/h3&gt; &lt;p&gt;Right click on the solution and go to Add New Item then select the ADO.NET Entity Data Model.&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/TcS_rHxVkJI/AAAAAAAAAZE/RPNJ63cj9oE/s1600-h/AddNewItem%5B7%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="AddNewItem" border="0" alt="AddNewItem" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TcS_sDfl2II/AAAAAAAAAZI/afAaA-DiPoc/AddNewItem_thumb%5B3%5D.jpg?imgmax=800" width="538" height="384"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Then choose &lt;strong&gt;“Generate from Database”.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TcS_smhqsDI/AAAAAAAAAZM/vSGg4HJv8T4/s1600-h/GenerateFromDatabase%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="GenerateFromDatabase" border="0" alt="GenerateFromDatabase" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TcS_ta63oxI/AAAAAAAAAZQ/7KEmpGC4bcA/GenerateFromDatabase_thumb%5B2%5D.jpg?imgmax=800" width="546" height="502"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You will then want to create a connection that points to your MySQL Database. &lt;/p&gt; &lt;p&gt;Go to &lt;strong&gt;New Connection. Note: &lt;/strong&gt;by default the Data Source will be set to &lt;strong&gt;Microsoft SQL Server (SqlClient)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Click&lt;strong&gt; “Change”&lt;/strong&gt; and select the Data source and Data Provider as shown below.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TcS_uSaiPfI/AAAAAAAAAZU/mCJMP3xbWqo/s1600-h/NewConnectionString%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="NewConnectionString" border="0" alt="NewConnectionString" src="http://lh3.ggpht.com/_la3Rv-0jOCI/TcS_u-g3Y7I/AAAAAAAAAZY/yIb5rsJZcMs/NewConnectionString_thumb%5B3%5D.jpg?imgmax=800" width="556" height="521"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;After doing this you enter your connection properties, shown below. &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TcS_vYgrDNI/AAAAAAAAAZc/ZGtJhCd7LeQ/s1600-h/ConnectionProperties%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ConnectionProperties" border="0" alt="ConnectionProperties" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TcS_wId19bI/AAAAAAAAAZg/EWXC69eQWcE/ConnectionProperties_thumb%5B3%5D.jpg?imgmax=800" width="304" height="316"&gt;&lt;/a&gt;&lt;/p&gt;   &lt;p&gt;Once you press &lt;strong&gt;OK &lt;/strong&gt;you will be presented with your database objects like below. Select all the Tables, Views &amp;amp; Stored Procedures you want to include in your model and press &lt;strong&gt;Finish&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TcS_w-KY1vI/AAAAAAAAAZk/-mQRx3Ts5xc/s1600-h/DatabaseObjects%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DatabaseObjects" border="0" alt="DatabaseObjects" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TcS_xXpUySI/AAAAAAAAAZo/hOY8nIeYL5M/DatabaseObjects_thumb%5B2%5D.jpg?imgmax=800" width="550" height="513"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Follow the &lt;strong&gt;“Next” &lt;/strong&gt;buttons through the wizard until your Model has been created. &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TcS_yLXjnRI/AAAAAAAAAZs/RL2losM2_zY/s1600-h/EFModel%5B6%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="EFModel" border="0" alt="EFModel" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TcS_yr3OuZI/AAAAAAAAAZw/hNPlgHfD4Os/EFModel_thumb%5B4%5D.jpg?imgmax=800" width="523" height="395"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Testing the Object Context&lt;/h3&gt; &lt;p&gt;To make sure that we can use the ObjectContext correctly I wrote a quick test in a console app. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;internal class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;context = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EFDemoEntities&lt;/span&gt;())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;category = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Category
                                   &lt;/span&gt;{
                                       Name = &lt;span style="color: #a31515"&gt;"Developer Tools"
                                   &lt;/span&gt;};

                &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product
                                  &lt;/span&gt;{
                                      Name = &lt;span style="color: #a31515"&gt;"Visual Studio 2010"
                                  &lt;/span&gt;};

                category.Products.Add(product);

                context.Categories.AddObject(category); 

                context.SaveChanges();

                category = context.Categories.FirstOrDefault();

                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"CategoryId: " &lt;/span&gt;+ category.Id);

                product = context.Products.FirstOrDefault();

                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"ProductId: " &lt;/span&gt;+ product.Id);

            }
        }
    }&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;font face="Trebuchet MS"&gt;And the output.&lt;/font&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TcS_zJh8cvI/AAAAAAAAAZ0/O7C8wk_3s-s/s1600-h/commandline%5B3%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="commandline" border="0" alt="commandline" src="http://lh4.ggpht.com/_la3Rv-0jOCI/TcS_z9_UlzI/AAAAAAAAAZ4/-8-7nDB-7Qk/commandline_thumb%5B1%5D.jpg?imgmax=800" width="500" height="283"&gt;&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;If you receive “&lt;strong&gt;&lt;em&gt;The specified value is not an instance of a valid constant type Parameter name: value”&lt;/em&gt;&lt;/strong&gt; when trying to do an insert of a related entity then make sure that the foreign key column is not UNSIGNED. The MySQL connector does not support UNSIGNED columns as foreign keys,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I’ve only covered the basic steps to using MySQL with Entity Framework 4.&lt;/p&gt;
&lt;p&gt;I have not used this yet in production, however it seems that MySQL and Entity Framework 4 is now a viable solution for those not married to SQL Server. &lt;/p&gt;
&lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/EXIDdXi6Fl4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/EXIDdXi6Fl4/using-entity-framework-4-with-mysql.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_la3Rv-0jOCI/TcS_sDfl2II/AAAAAAAAAZI/afAaA-DiPoc/s72-c/AddNewItem_thumb%5B3%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/05/using-entity-framework-4-with-mysql.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-87067504364530571</guid><pubDate>Fri, 29 Apr 2011 01:01:00 +0000</pubDate><atom:updated>2011-04-29T09:01:49.772+08:00</atom:updated><title>Downloading Amazon Kindle app for iPad2 in Singapore</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Last week I got my brand spanking new &lt;a href="http://www.apple.com/sg/ipad/" target="_blank"&gt;iPad 2&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;One of the major reasons I wanted this piece of technical indulgence is to use as a e-book reader on the daily commute.&amp;#160; &lt;/p&gt;  &lt;p&gt;So after plugging it in for the first time and going through the arduous ceremony of setting it up and doing the software update you can imagine my dismay when I discovered that the &lt;a href="http://itunes.apple.com/us/app/kindle/id302584613?mt=8" target="_blank"&gt;Kindle App&lt;/a&gt; was not available in the Singapore App Store. &lt;/p&gt;  &lt;p&gt;Now I’m already used to the fact that there is no Music or Video content in the Singapore version of iTunes and get by quite happily without it. But disallowing the downloading of a free app is taking it a bit too far. &lt;/p&gt;  &lt;p&gt;Fortunately for those in Singapore there is a workaround. &lt;/p&gt;  &lt;h3&gt;VPost &lt;/h3&gt;  &lt;p&gt;The first step is to create a &lt;a href="https://www.vpost.com.sg/" target="_blank"&gt;VPost&lt;/a&gt; account. &lt;/p&gt;  &lt;p&gt;For those who don’t know VPost is a service run by Singapore Post that effectively gives you a shipping address in either Japan, Europe or the United States. You can then get online shopping orders delivered to this address and they will forward the items to your Singapore based address. &lt;/p&gt;  &lt;p&gt;It’s a great service which has many uses and I thoroughly recommended it to anyone. &lt;/p&gt;  &lt;h3&gt;Another iTunes Account&lt;/h3&gt;  &lt;p&gt;Once you’ve got your VPost address in the US you’ll need to create a new iTunes account using your US based address and not linked to your credit card as iTunes validates the billing address of the credit card against the address entered in the sign up form and prevents from signing up if the country is not the same. &lt;/p&gt;  &lt;p&gt;The full list of steps are listed on the Apple Support site &lt;a href="http://support.apple.com/kb/ht2534"&gt;http://support.apple.com/kb/ht2534&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Downloading the Kindle App&lt;/h3&gt;  &lt;p&gt;Now that you have your US based iTunes account you can back to your iPad go to Settings &amp;gt; Store then sign-out of your existing account and sign-in using your new account.&amp;#160; &lt;/p&gt;  &lt;p&gt;Next up go to the App Store the search for “kindle” and low and behold it should appear and be able to be downloaded.&lt;/p&gt;  &lt;p&gt;Because your US account has no payment information tied to it, you’ll need to remember to sign out and sign in using your Singapore based account whenever you want to buy any apps. &lt;/p&gt;  &lt;h3&gt;Amazon Account&lt;/h3&gt;  &lt;p&gt;Now that you have the Kindle app you’ll need to create an Amazon account in order to be able to buy books. &lt;/p&gt;  &lt;p&gt;It is possible to use your Singapore address for this account, but bear in mind that there are quite a lot of books which are not available in the Asia-Pacific region. So to get around this you can use your US based VPost address and you will get access to all &lt;/p&gt;  &lt;p&gt;To get started go to the &lt;a href="https://www.amazon.com/ap/signin?_encoding=UTF8&amp;amp;openid.assoc_handle=usflex&amp;amp;openid.return_to=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fyourstore%3Fie%3DUTF8%26ref_%3Dpd_irl_gw_r&amp;amp;openid.mode=checkid_setup&amp;amp;openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&amp;amp;openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&amp;amp;openid.pape.max_auth_age=0&amp;amp;openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&amp;amp;openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select" target="_blank"&gt;sign in page&lt;/a&gt; and select “No, I am a new customer”.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;Despite the hoops you have to jump through to both download the App and then get the content this workaround does make it all possible. &lt;/p&gt;  &lt;p&gt;Hope this helps someone. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/u5ss5Hx1LqU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/u5ss5Hx1LqU/downloading-amazon-kindle-app-for-ipad2.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>14</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/04/downloading-amazon-kindle-app-for-ipad2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-4956481402720158982</guid><pubDate>Tue, 22 Feb 2011 14:00:00 +0000</pubDate><atom:updated>2011-03-01T19:20:10.845+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DDD</category><category domain="http://www.blogger.com/atom/ns#">entity framework</category><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">linq</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Specification Pattern, Entity Framework &amp; LINQ</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Firstly just to clarify I am going to be talking about the OOP Specification Pattern not the data pattern commonly found in the &lt;a href="http://www.tmforum.org/BestPracticesStandards/InformationFramework/1684/Home.html" target="_blank"&gt;SID (Shared Information &amp;amp; Data)&lt;/a&gt; model.&lt;/p&gt;  &lt;p&gt;Much has been said about the specification pattern so I’m not going to go into that, if you want an overview check out these posts: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.lostechies.com/blogs/chrismissal/archive/2009/09/10/using-the-specification-pattern-for-querying.aspx"&gt;http://www.lostechies.com/blogs/chrismissal/archive/2009/09/10/using-the-specification-pattern-for-querying.aspx&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://devlicio.us/blogs/jeff_perrin/archive/2006/12/13/the-specification-pattern.aspx"&gt;http://devlicio.us/blogs/jeff_perrin/archive/2006/12/13/the-specification-pattern.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In this post I’m going to demonstrate how you can make use of the specification pattern to query Entity Framework and create reusable, testable query objects and eliminate inline LINQ queries.&lt;/p&gt;  &lt;h3&gt;The Smell&lt;/h3&gt;  &lt;p&gt;When I first got started with Entity Framework way back in 2008 when EF was still in it’s infancy we had lot’s of inline LINQ all over the code base and specific methods on our repositories for querying requirements (which any OOP purist will tell you is bad). &lt;/p&gt;  &lt;p&gt;We had a service layer method which more or less looked something like: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;     public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; FindAllActiveProducts(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
     {
         &lt;span style="color: blue"&gt;return &lt;/span&gt;productRepository.FindAllActive(keyword); 
     }&lt;/pre&gt;
&lt;font face="Trebuchet MS"&gt;And then on our repository a method which looked like: &lt;/font&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; FindAllActive(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;query = context.CreateObjectSet&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;().Include(&lt;span style="color: #a31515"&gt;&amp;quot;Category&amp;quot;&lt;/span&gt;);


            &lt;span style="color: blue"&gt;var &lt;/span&gt;products = &lt;span style="color: blue"&gt;from &lt;/span&gt;p &lt;span style="color: blue"&gt;in &lt;/span&gt;query
                           &lt;span style="color: blue"&gt;where &lt;/span&gt;p.IsActive
                                 &amp;amp;&amp;amp; p.Name.Contains(keyword)
                           &lt;span style="color: blue"&gt;select &lt;/span&gt;p;

            &lt;span style="color: blue"&gt;return &lt;/span&gt;products.ToList();

        }&lt;/pre&gt;

&lt;p&gt;Now whilst this is not all bad it does present a few code smells:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You end up with lot’s of methods on your repositories to handle different query scenarios &lt;/li&gt;

  &lt;li&gt;There’s no way to test the query in isolation &lt;/li&gt;

  &lt;li&gt;Magic strings for the Include path &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not going to touch on whether or not you should be using repositories for this type of query scenario because that’s a whole other &lt;a href="http://cqrsinfo.com/" target="_blank"&gt;topic&lt;/a&gt; and a quick Google search will yield many posts debating this very subject.&amp;#160; &lt;/p&gt;

&lt;p&gt;However I will say that if you find yourself with lot’s of methods on your repositories that only perform query operations then this is a big code smell.&lt;/p&gt;

&lt;h3&gt;The Specification Interface&lt;/h3&gt;

&lt;p&gt;The first step is to define an interface for our Specification. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;
   {
       &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; Predicate { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }

       &lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; FetchStrategy { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

       &lt;span style="color: blue"&gt;bool &lt;/span&gt;IsSatisifedBy(T entity);
   }&lt;/pre&gt;

&lt;p&gt;If you’re familiar with this pattern you will notice the addition of two properties &lt;strong&gt;Predicate&lt;/strong&gt; and &lt;strong&gt;FetchStrategy&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The Predicate is ultimately what will be using to perform the query. You will notice this is read-only which forces it to be defined within the specification implementation. &lt;/p&gt;

&lt;p&gt;The FetchStrategy is an abstraction which defines the child objects that should be retrieved when loading the entity. More on this below. &lt;/p&gt;

&lt;h3&gt;Fetch Strategy&lt;/h3&gt;

&lt;p&gt;For those of you who don’t know when you load an entity from EF &amp;amp; other ORMs you can choose to either load just the root properties or load the related entities at the same time. The way to do this is in EF is by using the &lt;strong&gt;.Include&lt;/strong&gt; method on the &lt;strong&gt;ObjectQuery&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This works fine, however fetch strategies are likely needed to be reused in different places so having the .Include with magic strings everywhere becomes a real maintenance headache. &lt;/p&gt;

&lt;p&gt;In order to alleviate this pain I’ve created an abstraction on the concept.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt;
   {
       &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; IncludePaths { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }

       &lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; Include(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; path);

       &lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; Include(&lt;span style="color: blue"&gt;string &lt;/span&gt;path);
   }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#222222"&gt;Here is a generic implementation of this IFetchStrategy. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt;
    {
        &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; properties;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;GenericFetchStrategy()
        {
            properties = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();
        }

        &lt;span style="color: blue"&gt;#region &lt;/span&gt;IFetchStrategy&amp;lt;T&amp;gt; Members

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; IncludePaths
        {
            &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;properties; }
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; Include(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; path)
        {
            properties.Add(path.ToPropertyName());
            &lt;span style="color: blue"&gt;return this&lt;/span&gt;;
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; Include(&lt;span style="color: blue"&gt;string &lt;/span&gt;path)
        {
            properties.Add(path);
            &lt;span style="color: blue"&gt;return this&lt;/span&gt;;
        }

        &lt;span style="color: blue"&gt;#endregion
    &lt;/span&gt;}

    &lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Extensions
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public static string &lt;/span&gt;ToPropertyName&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; selector)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;me = selector.Body &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemberExpression&lt;/span&gt;;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(me == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;MemberException expected.&amp;quot;&lt;/span&gt;);
            }

            &lt;span style="color: blue"&gt;var &lt;/span&gt;propertyName = me.ToString().Remove(0, 2);
            &lt;span style="color: blue"&gt;return &lt;/span&gt;propertyName;
        }
    }&lt;/pre&gt;

&lt;p&gt;This is all fairly self explanatory, all it does is maintain a list of the include paths and provides a fluent interface. All the &lt;strong&gt;ToPropertyName &lt;/strong&gt;extension does is take a LINQ expression and returns the name of the property. &lt;/p&gt;

&lt;p&gt;Do note however that there is still one &lt;strong&gt;Include &lt;/strong&gt;method that takes a string as the parameter. 

  &lt;br /&gt;This is here to support really deep object hierarchies which can’t be represented as an expression.&lt;/p&gt;

&lt;p&gt;You could easily create your own implementations for each scenario e.g. &lt;strong&gt;FullProductFetchStrategy&lt;/strong&gt; and use that, however I tend to define the fetch strategy within the specification itself as you will soon see. &lt;/p&gt;

&lt;h3&gt;The Specification Implementation &lt;/h3&gt;

&lt;p&gt;First off we have a base class which contains the basic functionality and implements the ISpecification interface. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SpecificationBase&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;
    {
        &lt;span style="color: blue"&gt;protected &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; fetchStrategy;
        &lt;span style="color: blue"&gt;protected &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; predicate;

        &lt;span style="color: blue"&gt;protected &lt;/span&gt;SpecificationBase()
        {
            fetchStrategy = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt;();
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; Predicate
        {
            &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;predicate; }
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; FetchStrategy
        {
            &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;fetchStrategy; }
            &lt;span style="color: blue"&gt;set &lt;/span&gt;{ fetchStrategy = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsSatisifedBy(T entity)
        {
            &lt;span style="color: blue"&gt;return new&lt;/span&gt;[] {entity}.AsQueryable().Any(predicate); 
        }
    }&lt;/pre&gt;

&lt;p&gt;I have given the fetch strategy a getter &amp;amp; setter as it provides a bit of flexibility to the consumers but arguably you could make this read only and force instantiation in the constructor. &lt;/p&gt;

&lt;p&gt;Now returning to the original example of finding active products with a similar name to the keyword provided here is the &lt;strong&gt;ActiveProductsByNameSpec.&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;SpecificationBase&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;
   {
       &lt;span style="color: blue"&gt;public &lt;/span&gt;ActiveProductsByNameSpec(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
       {
           predicate = p =&amp;gt; p.Name.Contains(keyword) &amp;amp;&amp;amp; p.IsActive;

           fetchStrategy = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericFetchStrategy&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;().Include(p =&amp;gt; p.Category);
       }
   }&lt;/pre&gt;

&lt;p&gt;As you can see everything is defined in the constructor. &lt;/p&gt;

&lt;p&gt;Now you could expose a property for the keyword argument and have a single function which builds the predicate. &lt;/p&gt;

&lt;p&gt;My preference however is to do everything in the constructor as it is immediately obvious what the requirements for this class are and by exposing properties you risk having required values not set leading to subtle bugs.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Testing the Specification &lt;/h3&gt;

&lt;p&gt;Testability for me is one the greatest benefits of using this pattern. With deep object graphs LINQ queries can soon grow in size and complexity. More code == More chance of bugs. &lt;/p&gt;

&lt;p&gt;I can count 4 different test cases for this spec and here’s how we can test them. &lt;/p&gt;

&lt;pre class="code"&gt;&amp;#160;&lt;/pre&gt;

&lt;pre class="code"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;When_Product_Not_Active_Predicate_Should_Find_No_Match()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{IsActive = &lt;span style="color: blue"&gt;false&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot;&lt;/span&gt;};
            
            &lt;span style="color: blue"&gt;var &lt;/span&gt;spec = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot;&lt;/span&gt;);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = spec.IsSatisifedBy(product); 

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsFalse(actual);

        }

        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void 
            &lt;/span&gt;When_Product_IsActive_But_Does_Not_Contain_Keyword_Predicate_Should_Find_No_Match()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{ IsActive = &lt;span style="color: blue"&gt;true&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Visual Studio&amp;quot; &lt;/span&gt;};

            &lt;span style="color: blue"&gt;var &lt;/span&gt;spec = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot;&lt;/span&gt;);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = spec.IsSatisifedBy(product);

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsFalse(actual);

        }

        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void 
            &lt;/span&gt;When_Product_Does_Not_Contain_Keyword_And_Is_Not_Active_Predicate_Should_Find_No_Match()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{ IsActive = &lt;span style="color: blue"&gt;false&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Visual Studio&amp;quot; &lt;/span&gt;};

            &lt;span style="color: blue"&gt;var &lt;/span&gt;spec = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot;&lt;/span&gt;);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = spec.IsSatisifedBy(product);

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsFalse(actual);
        }

        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void 
            &lt;/span&gt;When_Product_IsActive_And_Contains_Keyword_Predicate_Should_Find_Match()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{ IsActive = &lt;span style="color: blue"&gt;true&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot; &lt;/span&gt;};

            &lt;span style="color: blue"&gt;var &lt;/span&gt;spec = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Resharper&amp;quot;&lt;/span&gt;);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = spec.IsSatisifedBy(product);

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(actual);
        }&lt;/pre&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;The Generic Repository&lt;/h3&gt;

&lt;p&gt;Now that we have our spec we need to create a generic repository which takes the ISpecification interface and returns some Entities. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IGenericQueryRepository
   &lt;/span&gt;{
       T Load&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec);

       &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; LoadAll&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec);

       &lt;span style="color: blue"&gt;bool &lt;/span&gt;Matches&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec);
   }&lt;/pre&gt;

&lt;p&gt;And this is implemented by: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericQueryRepository &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IGenericQueryRepository
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObjectContext &lt;/span&gt;context;

        &lt;span style="color: blue"&gt;#region &lt;/span&gt;IGenericQueryRepository Members

        &lt;span style="color: blue"&gt;public &lt;/span&gt;T Load&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;query = GetQuery(spec.FetchStrategy);

            &lt;span style="color: blue"&gt;return &lt;/span&gt;query.FirstOrDefault(spec.Predicate);
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; LoadAll&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;query = GetQuery(spec.FetchStrategy);

            &lt;span style="color: blue"&gt;return &lt;/span&gt;query.ToList();
        }

        &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Matches&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; spec)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;query = GetQuery(spec.FetchStrategy);

            &lt;span style="color: blue"&gt;return &lt;/span&gt;query.Any(spec.Predicate);
        }

        &lt;span style="color: blue"&gt;#endregion

        private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; GetQuery&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;IFetchStrategy&lt;/span&gt;&amp;lt;T&amp;gt; fetchStrategy)
        {
            &lt;span style="color: #2b91af"&gt;ObjectQuery&lt;/span&gt;&amp;lt;T&amp;gt;&lt;span style="color: blue"&gt; &lt;/span&gt;query = context.CreateObjectSet&amp;lt;T&amp;gt;();

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(fetchStrategy == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: blue"&gt;return &lt;/span&gt;query;
            }

            &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;path &lt;span style="color: blue"&gt;in &lt;/span&gt;fetchStrategy.IncludePaths)
            {
                query = query.Include(path);
            }

            &lt;span style="color: blue"&gt;return &lt;/span&gt;query;
        }
    }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Pulling it all together&lt;/h3&gt;

&lt;p&gt;Now that we have a generic repository we can safely get rid of the &lt;strong&gt;FindAllActive&lt;/strong&gt; method on our &lt;strong&gt;ProductRepository &lt;/strong&gt;and instead change our service layer to depend on the &lt;strong&gt;IGenericQueryRepository &lt;/strong&gt;and instantiate the specification like so.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; FindAllActiveProducts(&lt;span style="color: blue"&gt;string &lt;/span&gt;keyword)
       {
           &lt;span style="color: blue"&gt;var &lt;/span&gt;spec = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActiveProductsByNameSpec&lt;/span&gt;(keyword);

           &lt;span style="color: blue"&gt;return &lt;/span&gt;queryRepository.LoadAll(spec); 
       }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Well that’s it. I hope I’ve demonstrated how you can reduce the number of inline LINQ queries and ease the testability of such queries. On my team it is now a rule that all LINQ to Entities queries are defined as Specifications. &lt;/p&gt;

&lt;p&gt;The only element of this approach that is specific to Entity Framework is the fetch strategy approach I’ve used and I’m sure this could be easily adapted to fit with other ORMs that support LINQ.&lt;/p&gt;

&lt;p&gt;As always I’m happy to hear any feedback and feel free to contact me should you need any clarification. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/jTu8qYD9Eg4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/jTu8qYD9Eg4/specification-pattern-entity-framework.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>7</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/02/specification-pattern-entity-framework.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-8611455150206451612</guid><pubDate>Tue, 01 Feb 2011 14:00:00 +0000</pubDate><atom:updated>2011-06-02T20:19:22.372+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">xaml</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">workflow</category><category domain="http://www.blogger.com/atom/ns#">.net 4</category><category domain="http://www.blogger.com/atom/ns#">visual studio 2010</category><title>Managing Change in Long Running Workflows Part 2</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Recently I &lt;a href="http://blog.willbeattie.net/2010/11/managing-change-in-long-running.html" target="_blank"&gt;wrote&lt;/a&gt; about how some of the Serialization problems you can face when dealing with long running workflows. In this post I’m going to cover how I deal with logic changes in persisted workflows and also how you can make logic changes to your workflows without having to deploy code. &lt;/p&gt;  &lt;h3&gt;Hosting the Workflow&lt;/h3&gt;  &lt;p&gt;When it comes to hosting your workflows there are really only two options to consider. &lt;/p&gt;  &lt;p&gt;Self-Hosting    &lt;br /&gt;WCF Workflow Service&lt;/p&gt;  &lt;p&gt;To be honest I only looked at the WCF Workflow Service model briefly and decided it wasn’t the best fit for the requirements as it couldn’t provide the same benefits of self-hosting within a &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.workflowapplication.aspx" target="_blank"&gt;Workflow Application&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;  &lt;h3&gt;Workflow Instance Store&lt;/h3&gt;  &lt;p&gt;In order to persist Workflow instances you need to first create the Workflow Instance Store database. &lt;/p&gt;  &lt;p&gt;For this you will need to use the following scripts:&lt;/p&gt;  &lt;p&gt;C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreSchema.sql    &lt;br /&gt;C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreLogic.sql&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;&lt;strong&gt;The Workflow&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;The scenario I’m going to use for this post is that of an order approval workflow. So after an order is created it goes into a &lt;strong&gt;“Pending” &lt;/strong&gt;state, a workflow is then started requiring two users to approve before it can be changed to an &lt;strong&gt;“Approved” &lt;/strong&gt;state.&lt;/p&gt;  &lt;p&gt;This is represented in the below diagram.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TUaygj8DVPI/AAAAAAAAAYw/JjscMbLj87g/s1600-h/OrderApprovalWorkflow7.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OrderApprovalWorkflow" border="0" alt="OrderApprovalWorkflow" src="http://lh4.ggpht.com/_la3Rv-0jOCI/TUayhV_Ad1I/AAAAAAAAAY0/FouIekFus2I/OrderApprovalWorkflow_thumb2.jpg?imgmax=800" width="608" height="507" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Bookmarks&lt;/h3&gt;  &lt;p&gt;If you already know how to implement long running workflows using &lt;a href="http://msdn.microsoft.com/en-us/library/dd489442.aspx" target="_blank"&gt;Bookmarks&lt;/a&gt; then you can skip down to the next section. &lt;/p&gt;  &lt;p&gt;The way to have points in your workflows that trigger persistence and can wait for external input are called &lt;a href="http://msdn.microsoft.com/en-us/library/dd489442.aspx" target="_blank"&gt;Bookmarks&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In above diagram the &lt;strong&gt;“Wait for Approval” &lt;/strong&gt;activity is a Bookmark and looks like the following:&lt;/p&gt;  &lt;pre class="code"&gt; [&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]
 &lt;span style="color: blue"&gt;public sealed class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WaitForApproval &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;NativeActivity&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;
 {
     &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; UserId { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

     &lt;span style="color: blue"&gt;protected override bool &lt;/span&gt;CanInduceIdle
     {
         &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return true&lt;/span&gt;; }
     }

     &lt;span style="color: blue"&gt;protected override void &lt;/span&gt;Execute(&lt;span style="color: #2b91af"&gt;NativeActivityContext &lt;/span&gt;context)
     {
         &lt;span style="color: blue"&gt;var &lt;/span&gt;bookmarkName = &lt;span style="color: #a31515"&gt;&amp;quot;waitingFor_&amp;quot; &lt;/span&gt;+ UserId.Get(context);

         context.CreateBookmark(bookmarkName, OnReadComplete);
     }

     &lt;span style="color: blue"&gt;private void &lt;/span&gt;OnReadComplete(&lt;span style="color: #2b91af"&gt;NativeActivityContext &lt;/span&gt;context, &lt;span style="color: #2b91af"&gt;Bookmark &lt;/span&gt;bookmark, &lt;span style="color: blue"&gt;object &lt;/span&gt;state)
     {
         &lt;span style="color: blue"&gt;var &lt;/span&gt;input = &lt;span style="color: #2b91af"&gt;Convert&lt;/span&gt;.ToBoolean(state, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;EN-us&amp;quot;&lt;/span&gt;));

         context.SetValue(Result, input);
     }
 }&lt;/pre&gt;

&lt;p&gt;Take note of the bookmark name as this will be used later when resuming the workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; The bookmark is stored in the BlockingBookmarks field on your InstancesTable in your workflow instance database.&lt;/p&gt;

&lt;h3&gt;The Problem&lt;/h3&gt;

&lt;p&gt;The problem you can face after you’ve persisted your workflow instance is when the workflow definition changes and you try to load the instance using &lt;a href="http://msdn.microsoft.com/en-us/library/ee473640.aspx" target="_blank"&gt;WorkflowApplication.Load&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A number of changes detailed below can lead to invalidating the workflow instance and will cause a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.validationexception.aspx" target="_blank"&gt;System.Activities.ValidationException&lt;/a&gt; to be thrown.&lt;/p&gt;

&lt;p&gt;The somewhat “official&amp;quot; word on this found &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wfprerelease/thread/071e85d7-7f99-41da-83db-b5b5f45bf2d9/" target="_blank"&gt;here&lt;/a&gt; is that “WF4 is not able to handle runtime changes to the workflow definition”. This was &lt;a href="http://social.msdn.microsoft.com/Forums/en/wfprerelease/thread/7cb152d0-419f-4cb0-bed2-cb8a69c8bb52" target="_blank"&gt;elaborated&lt;/a&gt; a bit more and here are the “official” lists of breaking and non-breaking changes. &lt;/p&gt;

&lt;p&gt;Non-Breaking Changes: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Changes to the activities code &lt;/li&gt;

  &lt;li&gt;Changes which don’t affect the number or types of arguments/variables &lt;/li&gt;

  &lt;li&gt;Addition or removal of member fields or properties &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Breaking Changes: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Renaming or removing methods that had been used as bookmark, fault or completion callbacks &lt;/li&gt;

  &lt;li&gt;Adding new arguments &lt;/li&gt;

  &lt;li&gt;Adding new variables &lt;/li&gt;

  &lt;li&gt;Adding new children &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically the rules of serialization/deserialization versioning apply also to workflows, which when you think about it makes sense.&lt;/p&gt;

&lt;p&gt;Don’t fret though as this can be avoided without too much effort, so keep reading to find out how. &lt;/p&gt;

&lt;h3&gt;Incorporating Workflow into the Architecture&lt;/h3&gt;

&lt;p&gt;Very early on in my foray with Workflow Foundation I realised the power and flexibility it could to add to the application, specifically the ability to use different workflows for different users/accounts and changing workflows at run-time. &lt;/p&gt;

&lt;p&gt;Because of this it was decided that the workflows should be treated as a first class citizen in our domain model and not just left as an abstract technical implementation of the business process. &lt;/p&gt;

&lt;p&gt;Below is a simple class diagram which should give you a good idea of the approach taken. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TUayiUp5eDI/AAAAAAAAAY4/7ndF03KHzEQ/s1600-h/ClassDiagram13.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://lh4.ggpht.com/_la3Rv-0jOCI/TUayjJJpz-I/AAAAAAAAAY8/ItrlCdOBGNA/ClassDiagram1_thumb1.png?imgmax=800" width="668" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the Order class there is the &lt;strong&gt;WorkflowInstanceId&lt;/strong&gt; and &lt;strong&gt;WorkflowXaml. 
    &lt;br /&gt;&lt;/strong&gt;The &lt;strong&gt;WorkflowInstanceId &lt;/strong&gt;is there because it allows to identify the Workflow by using the OrderId meaning that you don’t have to expose the InstanceId in other parts of your application.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;WorkflowXaml&lt;/strong&gt; is the raw definition of the workflow that gets copied from the WorkflowDefinition&lt;strong&gt; &lt;/strong&gt;at instantiation time. The purpose of this is to allow the WorkflowDefinition Xaml to be changed without affecting the persisted workflows and solves the problem described above. &lt;/p&gt;

&lt;p&gt;Arguably you could add a separate Class/Table which stores the active Xaml and InstanceId for the Order, but for simplicities sake I’ve just added them to the Order.&lt;/p&gt;

&lt;p&gt;It should also be said the &lt;strong&gt;WorkflowInstanceId &lt;/strong&gt;and&lt;strong&gt; WorkflowXaml&lt;/strong&gt; can be cleared from the Order table once the workflow has completed. &lt;/p&gt;

&lt;p&gt;This will all become clearer as you read on. &lt;/p&gt;

&lt;h3&gt;Generic Workflow Host&lt;/h3&gt;

&lt;p&gt;For the hosting I have come up with a GenericWorkflowHost which allows to start instances and resume from bookmarks. There’s not much that is very exciting in here although do take note of the following methods: 
  &lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CreateActivityFrom &lt;/li&gt;

  &lt;li&gt;StartPersistableInsance &lt;/li&gt;

  &lt;li&gt;LoadInstanceWithBookmark &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key part is the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.xaml.xamlservices.load.aspx" target="_blank"&gt;XamlServices.Load&lt;/a&gt; &lt;/strong&gt;method which allows to create an Activity using just the Xaml. This is important because this allows you to change the Xaml without re-compiling and deploying code. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Activities;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Activities.DurableInstancing;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Activities.XamlIntegration;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Concurrent;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Configuration;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.IO;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Reflection;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Runtime.DurableInstancing;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Xaml;

&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericWorkflowHost
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConcurrentDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;WorkflowApplication&lt;/span&gt;&amp;gt; runningWorkflows;

    &lt;span style="color: blue"&gt;#region &lt;/span&gt;Private Helper Methods 

    &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Activity &lt;/span&gt;CreateActivityFrom(&lt;span style="color: blue"&gt;string &lt;/span&gt;xaml)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;sr = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StringReader&lt;/span&gt;(xaml);

        &lt;span style="color: green"&gt;//Change LocalAssembly to where the Activities reside
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;xamlSettings = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XamlXmlReaderSettings
                               &lt;/span&gt;{LocalAssembly = &lt;span style="color: #2b91af"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly()};

        &lt;span style="color: blue"&gt;var &lt;/span&gt;xamlReader = &lt;span style="color: #2b91af"&gt;ActivityXamlServices
            &lt;/span&gt;.CreateReader(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;XamlXmlReader&lt;/span&gt;(sr, xamlSettings));

        &lt;span style="color: blue"&gt;var &lt;/span&gt;result = &lt;span style="color: #2b91af"&gt;XamlServices&lt;/span&gt;.Load(xamlReader);

        &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = result &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Activity&lt;/span&gt;;

        &lt;span style="color: blue"&gt;return &lt;/span&gt;activity;
    }

    &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InstanceStore &lt;/span&gt;CreateInstanceStore()
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;conn = &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[&lt;span style="color: #a31515"&gt;&amp;quot;WorkflowDbConn&amp;quot;&lt;/span&gt;].ConnectionString;

        &lt;span style="color: blue"&gt;var &lt;/span&gt;store = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlWorkflowInstanceStore&lt;/span&gt;(conn)
                        {
                            InstanceLockedExceptionAction = &lt;span style="color: #2b91af"&gt;InstanceLockedExceptionAction&lt;/span&gt;.AggressiveRetry,
                            InstanceCompletionAction = &lt;span style="color: #2b91af"&gt;InstanceCompletionAction&lt;/span&gt;.DeleteNothing,
                            HostLockRenewalPeriod = &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(20),
                            RunnableInstancesDetectionPeriod = &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(3)
                        };

        &lt;span style="color: blue"&gt;var &lt;/span&gt;handle = store.CreateInstanceHandle();

        &lt;span style="color: blue"&gt;var &lt;/span&gt;view = store.Execute(handle, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CreateWorkflowOwnerCommand&lt;/span&gt;(),
                                 &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(60));

        store.DefaultInstanceOwner = view.InstanceOwner;

        handle.Free();

        &lt;span style="color: blue"&gt;return &lt;/span&gt;store;
    }

   
    &lt;span style="color: blue"&gt;#endregion

    public static void &lt;/span&gt;InvokeInstance(&lt;span style="color: blue"&gt;object &lt;/span&gt;input, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml, &lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;instanceId)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;inputs = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;();

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(input != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
            inputs.Add(input.GetType().Name, input);
        }

        &lt;span style="color: blue"&gt;var &lt;/span&gt;wf = CreateActivityFrom(xaml);

        &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = wf;

        &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(activity, inputs);
    }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;StartPersistableInstance(&lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt; inputs, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(runningWorkflows == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
            runningWorkflows = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConcurrentDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;WorkflowApplication&lt;/span&gt;&amp;gt;();
        }


        &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = CreateActivityFrom(xaml);

        &lt;span style="color: blue"&gt;var &lt;/span&gt;workflowApp = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WorkflowApplication&lt;/span&gt;(activity, inputs)
                              {
                                  InstanceStore = CreateInstanceStore(),
                                  PersistableIdle = OnIdleAndPersistable,
                                  Completed = OnWorkflowCompleted,
                                  Aborted = OnWorkflowAborted,
                                  Unloaded = OnWorkflowUnloaded,
                                  OnUnhandledException = OnWorkflowException
                              };

        workflowApp.Persist();

        &lt;span style="color: blue"&gt;var &lt;/span&gt;instanceId = workflowApp.Id;

        workflowApp.Run();

        runningWorkflows.TryAdd(instanceId, workflowApp);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;workflowApp.Id;
    }

    &lt;span style="color: blue"&gt;public static bool &lt;/span&gt;LoadInstanceWithBookmark(&lt;span style="color: blue"&gt;string &lt;/span&gt;bookmarkName,
                                                &lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;instanceId,
                                                &lt;span style="color: blue"&gt;object &lt;/span&gt;input,
                                                &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(runningWorkflows == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
            runningWorkflows = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConcurrentDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;WorkflowApplication&lt;/span&gt;&amp;gt;();
        }

        &lt;span style="color: #2b91af"&gt;BookmarkResumptionResult &lt;/span&gt;result;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(runningWorkflows.ContainsKey(instanceId))
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;workflow = runningWorkflows[instanceId];
            workflow.Completed = OnWorkflowCompleted;
            workflow.PersistableIdle = OnIdleAndPersistable;

            result = workflow.ResumeBookmark(bookmarkName, input, &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(60));

            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(instanceId + &lt;span style="color: #a31515"&gt;&amp;quot; resumed @ &amp;quot; &lt;/span&gt;+ bookmarkName);
        }
        &lt;span style="color: blue"&gt;else
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;// Setup the persistance
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;store = CreateInstanceStore();

            &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = CreateActivityFrom(xaml);

            &lt;span style="color: blue"&gt;var &lt;/span&gt;application = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WorkflowApplication&lt;/span&gt;(activity)
                                  {
                                      InstanceStore = store,
                                      Completed = OnWorkflowCompleted,
                                      Unloaded = OnWorkflowUnloaded,
                                      PersistableIdle = OnIdleAndPersistable,
                                  };

            application.Load(instanceId, &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(60));

            result = application.ResumeBookmark(bookmarkName, input, &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(60));

            runningWorkflows.TryAdd(instanceId, application);

            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(instanceId + &lt;span style="color: #a31515"&gt;&amp;quot; resumed @ &amp;quot; &lt;/span&gt;+ bookmarkName);
        }

        &lt;span style="color: blue"&gt;return &lt;/span&gt;result == &lt;span style="color: #2b91af"&gt;BookmarkResumptionResult&lt;/span&gt;.Success;
    }

    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;UnloadInstance(&lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;instanceId)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!runningWorkflows.ContainsKey(instanceId))
        {
            &lt;span style="color: blue"&gt;return&lt;/span&gt;;
        }

        &lt;span style="color: blue"&gt;var &lt;/span&gt;workflow = runningWorkflows[instanceId];
        workflow.Unload();

        runningWorkflows.TryRemove(instanceId, &lt;span style="color: blue"&gt;out &lt;/span&gt;workflow);
    }

    &lt;span style="color: blue"&gt;#region &lt;/span&gt;Events 

    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;OnWorkflowCompleted(&lt;span style="color: #2b91af"&gt;WorkflowApplicationCompletedEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(runningWorkflows != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; runningWorkflows.ContainsKey(e.InstanceId))
        {
            &lt;span style="color: #2b91af"&gt;WorkflowApplication &lt;/span&gt;workflowApp;
            runningWorkflows.TryRemove(e.InstanceId, &lt;span style="color: blue"&gt;out &lt;/span&gt;workflowApp);
        }

        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(e.CompletionState);
    }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PersistableIdleAction &lt;/span&gt;OnIdleAndPersistable(&lt;span style="color: #2b91af"&gt;WorkflowApplicationIdleEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PersistableIdleAction&lt;/span&gt;.Unload;
    }

    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;OnWorkflowAborted(&lt;span style="color: #2b91af"&gt;WorkflowApplicationAbortedEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(e.Reason);
    }

    &lt;span style="color: blue"&gt;public static void &lt;/span&gt;OnWorkflowUnloaded(&lt;span style="color: #2b91af"&gt;WorkflowApplicationEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(runningWorkflows != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; runningWorkflows.ContainsKey(e.InstanceId))
        {
            &lt;span style="color: #2b91af"&gt;WorkflowApplication &lt;/span&gt;workflowApp;
            runningWorkflows.TryRemove(e.InstanceId, &lt;span style="color: blue"&gt;out &lt;/span&gt;workflowApp);
        }

        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(e.InstanceId + &lt;span style="color: #a31515"&gt;&amp;quot; unloaded&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UnhandledExceptionAction &lt;/span&gt;OnWorkflowException(&lt;span style="color: #2b91af"&gt;WorkflowApplicationUnhandledExceptionEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color: green"&gt;//log the exception here using e.UnhandledException 
        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UnhandledExceptionAction&lt;/span&gt;.Terminate;
    }

    &lt;span style="color: blue"&gt;#endregion
&lt;/span&gt;}&lt;/pre&gt;


&lt;p&gt;As you may have noticed the GenericWorkflowHost is a static class so I choose to abstract this away behind an interface so that it’s nice and Unit-Test friendly: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IOrderApprovalWorkflowHost
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;void &lt;/span&gt;Resume(&lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml, &lt;span style="color: blue"&gt;int &lt;/span&gt;userId, &lt;span style="color: blue"&gt;bool &lt;/span&gt;isApproved);

       &lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;Start(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml);
   }&lt;/pre&gt;

&lt;p&gt;Which is implemented like so: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OrderWorkflowApprovalHost &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IOrderApprovalWorkflowHost
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Resume(&lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml, &lt;span style="color: blue"&gt;int &lt;/span&gt;userId, &lt;span style="color: blue"&gt;bool &lt;/span&gt;isApproved)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;bookmark = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;waitingFor_{0}&amp;quot;&lt;/span&gt;, userId);

            &lt;span style="color: #2b91af"&gt;GenericWorkflowHost&lt;/span&gt;.LoadInstanceWithBookmark(bookmark, instanceId, isApproved, xaml); 
        }

        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;Start(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId, &lt;span style="color: blue"&gt;string &lt;/span&gt;xaml)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;inputs = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;()
                             {
                                 {&lt;span style="color: #a31515"&gt;&amp;quot;OrderId&amp;quot;&lt;/span&gt;, orderId}
                             };  
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GenericWorkflowHost&lt;/span&gt;.StartPersistableInstance(inputs, xaml);
        }

    }&lt;/pre&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;Starting the Workflow Instance&lt;/h3&gt;

&lt;p&gt;Now that we have our workflow host it’s time to start the workflow. I like to abstract any workflow calls behind a service interface that the other layers can consume without the hard-dependency on the workflow libraries. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IOrderApprovalService
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;void &lt;/span&gt;SubmitApproval(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId, &lt;span style="color: blue"&gt;int &lt;/span&gt;userId, &lt;span style="color: blue"&gt;bool &lt;/span&gt;isApproved);

        &lt;span style="color: blue"&gt;void &lt;/span&gt;StartApprovalWorkflow(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId); 
    }&lt;/pre&gt;

&lt;p&gt;The StartApprovalWorkflow method is implemented like so: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;StartApprovalWorkflow(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId)
        {
            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;unitOfWork = unitOfWorkFactory.Create())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;order = orderRepository.Get(orderId);

                &lt;span style="color: blue"&gt;var &lt;/span&gt;workflow = workflowRepository.Get(1); &lt;span style="color: green"&gt;// this id should come from configuration &lt;/span&gt;&lt;span style="color: green"&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;instanceId = orderApprovalWorkflowHost.Start(orderId, workflow.Xaml);

                order.StartWorkflow(workflow, instanceId);&lt;span style="color: green"&gt;// this sets the workflow xaml &amp;amp; instanceid&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;&lt;/span&gt;
                unitOfWork.Commit(); 

            }
        }&lt;/pre&gt;

&lt;p&gt;All we do here is load the Order &amp;amp; workflow from their respective repositories and then start the workflow and assign the workflow to the order. All pretty simple stuff. &lt;/p&gt;

&lt;h3&gt;Resuming the Workflow Instance&lt;/h3&gt;

&lt;p&gt;Resuming the instance is as easy as loading the Order and then calling the &lt;strong&gt;OrderApprovalWorkflowHost&lt;/strong&gt; passing the persisted Xaml &amp;amp; InstanceId that was saved when starting the workflow. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;SubmitApproval(&lt;span style="color: blue"&gt;int &lt;/span&gt;orderId, &lt;span style="color: blue"&gt;int &lt;/span&gt;userId, &lt;span style="color: blue"&gt;bool &lt;/span&gt;isApproved)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;order = orderRepository.Get(orderId);

            orderApprovalWorkflowHost
                .Resume(order.WorkflowInstanceId, order.WorkflowXaml, userId, isApproved);
        }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;The approach I’ve outlined in this post has some major benefits: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ability to change the workflow definition without code deployment &lt;/li&gt;

  &lt;li&gt;Ability to change workflow definition without invalidating persisted instances &lt;/li&gt;

  &lt;li&gt;Provides a simple way to view active instances &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you want to change the logic flow in a persisted instance the simplest approach is either to force the workflow to end and then restart it or to just rollback any state changes the workflow has done and simply restart a new instance then delete the old instance. This needs to be carefully thought out though especially if any of the activities send emails.&lt;/p&gt;

&lt;p&gt;Well that’s all I’ve got for this post, I’m really keen to hear any feedback and as always I’d be happy to answer any questions. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/OH9r2ukBZjI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/OH9r2ukBZjI/managing-change-in-long-running.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_la3Rv-0jOCI/TUayhV_Ad1I/AAAAAAAAAY0/FouIekFus2I/s72-c/OrderApprovalWorkflow_thumb2.jpg?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.willbeattie.net/2011/02/managing-change-in-long-running.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-2342518058170916744</guid><pubDate>Thu, 25 Nov 2010 13:00:00 +0000</pubDate><atom:updated>2010-11-25T21:00:12.599+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">workflow</category><category domain="http://www.blogger.com/atom/ns#">.net 4</category><title>Managing Change in Long Running Workflows Part 1</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I’ve been using &lt;a href="http://msdn.microsoft.com/en-us/netframework/aa663328.aspx" target="_blank"&gt;Workflow Foundation&lt;/a&gt; now for over a year and it has become an integral part of our architecture and has by and large been very successful. However it is not without it’s issues, the single most being that official documentation is light at best and relevant blog posts are quite rare.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;I recently ran into a fairly serious problem after deploying a new release of &lt;a href="http://www.ebus.tv/" target="_blank"&gt;our Software.&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;The Problem&lt;/h4&gt;  &lt;p&gt;I received this lovely email from our exception tracker:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}LoadWorkflow was interrupted by an error. ---&amp;gt; System.Runtime.Serialization.SerializationException: Deserialized object with reference id '73' not found in stream.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The key part is &lt;strong&gt;“Deserialized object with reference id '73' not found in stream.” &lt;/strong&gt;As I’m sure you can tell this does not really provide any helpful information. &lt;/p&gt;  &lt;p&gt;The stack trace does give you some more information as to which property failed, but depending on the object graph the stack trace can be fairly massive. &lt;/p&gt;  &lt;p&gt;This is the part which gives you the biggest clue: &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;at ReadArrayOfPersonFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )&lt;/strong&gt;&lt;/p&gt;  &lt;h4&gt;The Cause&lt;/h4&gt;  &lt;p&gt;Basically what has happened here is that when trying to load an unloaded workflow instance from the SqlWorkflowInstanceStore the deserializer spits the dummy because a property on the object that existed at the time the Workflow was persisted no longer exists on the class.&amp;#160; &lt;/p&gt;  &lt;p&gt;Once you understand the cause it does seem reasonable, sort of. In my effort to clean up the solution and get rid of unused properties I had effectively broken every workflow instance which was persisted before the date of the latest release. &lt;/p&gt;  &lt;p&gt;As it turns out it’s possible to create this issue by either removing properties or renaming existing properties.&lt;/p&gt;  &lt;p&gt;I made the fatal mistake of using passing my Domain Entities into the workflow as an argument.&lt;/p&gt;  &lt;h4&gt;The Patch&lt;/h4&gt;  &lt;p&gt;In order to fix this issue I ended up scrambling through the check-in history over the last 6 weeks trying to figure which properties had been removed. Once I figured it out, I added them back and deployed a patch. This solved the problem and the crisis was averted for the short-term.&lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h4&gt;  &lt;p&gt;When a workflow is unloaded and persisted to the data store it is&lt;strong&gt; &lt;/strong&gt;serialized and all internal variables &amp;amp; arguments are serialized along with it. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rules for data objects in workflows:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Never ever under any circumstances use Domain Entities &lt;/li&gt;    &lt;li&gt;Always use DTO’s for &lt;strong&gt;Arguments&lt;/strong&gt; or &lt;strong&gt;Variables&lt;/strong&gt; in Long Running Workflows &lt;/li&gt;    &lt;li&gt;Set IsRequired=false on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx" target="_blank"&gt;DataMember&lt;/a&gt; attribute for all Nullable Properties &lt;/li&gt;    &lt;li&gt;Set the Name property on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx" target="_blank"&gt;DataMember&lt;/a&gt; attribute &lt;/li&gt;    &lt;li&gt;Set the Order Property on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx" target="_blank"&gt;DataMember&lt;/a&gt; attribute &lt;/li&gt;    &lt;li&gt;Set the Name on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank"&gt;DataContract&lt;/a&gt; attribute &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This is an example of a class that could create problems in the future. &lt;/p&gt;  &lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;DataContract&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Category
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public int &lt;/span&gt;Id { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

        [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; Products { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    }&lt;/pre&gt;

&lt;p&gt;Based on the above lessons here is how I would suggest coding this class for use in a Workflow. &lt;/p&gt;

&lt;pre class="code"&gt;   [&lt;span style="color: #2b91af"&gt;DataContract&lt;/span&gt;(Name=&lt;span style="color: #a31515"&gt;&amp;quot;Category&amp;quot;&lt;/span&gt;)]
   &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Category
   &lt;/span&gt;{
       [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;(IsRequired = &lt;span style="color: blue"&gt;false&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, Order=0)]
       &lt;span style="color: blue"&gt;public int &lt;/span&gt;Id { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

       [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;(IsRequired = &lt;span style="color: blue"&gt;false&lt;/span&gt;, Name = &lt;span style="color: #a31515"&gt;&amp;quot;Products&amp;quot;&lt;/span&gt;)]
       &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; Products { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
   }&lt;/pre&gt;

&lt;p&gt;By setting the Name property on the DataMember you are then free to change the property name without fear of breaking the deserialization. &lt;/p&gt;

&lt;p&gt;Setting IsRequired to False allows you to remove the property in the future without breaking deserialization, obviously you should set this for True for any properties that are truly required by the Workflow to function correctly.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;This is just an example of how to deal with data that changes in workflows, in my next post I’m going to cover how you deal with workflows whose logic changes after an instance has been created and persisted. &lt;/p&gt;

&lt;p&gt;I hope this helps anyone who’s working with Workflow Foundation or about to start using it. &lt;/p&gt;

&lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/FE06hltdxC4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/FE06hltdxC4/managing-change-in-long-running.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/11/managing-change-in-long-running.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-7384412403501812115</guid><pubDate>Wed, 24 Nov 2010 13:00:00 +0000</pubDate><atom:updated>2010-11-24T21:00:14.116+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">video</category><category domain="http://www.blogger.com/atom/ns#">mediainfo</category><title>MediaInfo deprecated attributes in Version 0.7.37</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I’ve just discovered that the latest version (0.7.37) of &lt;a href="http://mediainfo.sourceforge.net/"&gt;MediaInfo&lt;/a&gt; has some deprecated attributes and I’ve compiled the full list of deprecated attributes split by the Track type.&lt;/p&gt;  &lt;h4&gt;General &lt;/h4&gt;  &lt;p&gt;Menu_Codec_List    &lt;br /&gt;Format/String     &lt;br /&gt;Codec     &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url     &lt;br /&gt;Codec/Extensions     &lt;br /&gt;Codec_Settings     &lt;br /&gt;Codec_Settings_Automatic&lt;/p&gt;  &lt;h4&gt;Video &lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Family     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url     &lt;br /&gt;Codec/CC     &lt;br /&gt;Codec_Profile     &lt;br /&gt;Codec_Description     &lt;br /&gt;Codec_Settings     &lt;br /&gt;Codec_Settings_PacketBitStream     &lt;br /&gt;Codec_Settings_BVOP     &lt;br /&gt;Codec_Settings_QPel     &lt;br /&gt;Codec_Settings_GMC     &lt;br /&gt;Codec_Settings_GMC/String     &lt;br /&gt;Codec_Settings_Matrix     &lt;br /&gt;Codec_Settings_Matrix_Data     &lt;br /&gt;Codec_Settings_CABAC     &lt;br /&gt;Codec_Settings_RefFrames     &lt;br /&gt;Resolution     &lt;br /&gt;Resolution/String     &lt;br /&gt;Colorimetry     &lt;br /&gt;Interlacement     &lt;br /&gt;Interlacement/String&lt;/p&gt;  &lt;h4&gt;Audio&lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Family     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url     &lt;br /&gt;Codec/CC     &lt;br /&gt;Codec_Description     &lt;br /&gt;Codec_Profile     &lt;br /&gt;Codec_Settings     &lt;br /&gt;Codec_Settings_Automatic     &lt;br /&gt;Codec_Settings_Floor     &lt;br /&gt;Codec_Settings_Firm     &lt;br /&gt;Codec_Settings_Endianness     &lt;br /&gt;Codec_Settings_Sign     &lt;br /&gt;Codec_Settings_Law     &lt;br /&gt;Codec_Settings_ITU     &lt;br /&gt;Resolution     &lt;br /&gt;Resolution/String     &lt;br /&gt;Video0_Delay     &lt;br /&gt;Video0_Delay/String     &lt;br /&gt;Video0_Delay/String1     &lt;br /&gt;Video0_Delay/String2     &lt;br /&gt;Video0_Delay/String3     &lt;br /&gt;Video0_Delay/String4&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Image &lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Family     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url     &lt;br /&gt;Resolution     &lt;br /&gt;Resolution/String&lt;/p&gt;  &lt;h4&gt;Menu&lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url&lt;/p&gt;  &lt;h4&gt;Text&lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url     &lt;br /&gt;Codec/CC     &lt;br /&gt;Resolution     &lt;br /&gt;Resolution/String     &lt;br /&gt;Video0_Delay     &lt;br /&gt;Video0_Delay/String     &lt;br /&gt;Video0_Delay/String1     &lt;br /&gt;Video0_Delay/String2     &lt;br /&gt;Video0_Delay/String3     &lt;br /&gt;Video0_Delay/String4&lt;/p&gt;  &lt;h4&gt;Chapters&lt;/h4&gt;  &lt;p&gt;Codec    &lt;br /&gt;Codec/String     &lt;br /&gt;Codec/Info     &lt;br /&gt;Codec/Url&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you want the full list of all available attributes, then download the DLL version from the &lt;a href="http://mediainfo.sourceforge.net/en/Download/Windows"&gt;MediaInfo download page&lt;/a&gt; and go to the Developers/List_Of_Parameters folder. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/RznGfjhWhEk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/RznGfjhWhEk/mediainfo-deprecated-attributes-in.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/11/mediainfo-deprecated-attributes-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-8607192142684876254</guid><pubDate>Tue, 23 Nov 2010 13:00:00 +0000</pubDate><atom:updated>2010-11-23T21:00:09.033+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">sql server 2008</category><title>Consuming the SSRS ReportExecutionService from a .NET Client</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I’ve just finished writing a nice wrapper which internally calls the SSRS &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.wssux.reportingserviceswebservice.rsexecutionservice2005.reportexecutionservice(SQL.90).aspx" target="_blank"&gt;ReportExecutionService&lt;/a&gt; to generate reports.     &lt;br /&gt;Whilst it was fairly simple to implement there has been some major changes between 2005 and 2008 and the majority of online and documentation is based on the 2005 implementation. &lt;/p&gt;  &lt;p&gt;The most important change is that the Report Server and Report Manager are no longer hosted in IIS which will be a welcomed change to Sys Admins but makes the security model and hosting model vastly different. So far I’ve yet to figure out how to allow Anonymous Access, if anyone knows how to do this leave a comment and it will be most appreciated. &lt;/p&gt;  &lt;h4&gt;Getting Started&lt;/h4&gt;  &lt;p&gt;To get started you’ll want to add a service reference to &lt;a title="http://localhost/ReportServer_SQL2008/ReportExecution2005.asmx" href="http://localhost/ReportServer_SQL2008/ReportExecution2005.asmx"&gt;http://localhost/ReportServer_SQL2008/ReportExecution2005.asmx&lt;/a&gt; where &lt;strong&gt;ReportServer_SQL2008&lt;/strong&gt; is the name you configure in the Reporting Services Configuration Manager. &lt;/p&gt;  &lt;p&gt;The Web Application files are located in &lt;strong&gt;C:\Program Files\Microsoft SQL Server\MSRS10.SQL2008\Reporting Services, &lt;/strong&gt;you’ll want to to create a dedicated User and grant it permissions to these application folders.&lt;/p&gt;  &lt;p&gt;Once you’ve done that you’ll need to browse to the Report Manager logging in as an Administrator account and then add a Role for your new user under the Security page &lt;a href="http://localhost/Reports_SQL2008/Pages/Settings.aspx?SelectedSubTabId=SecurityLinkID"&gt;http://localhost/Reports_SQL2008/Pages/Settings.aspx?SelectedSubTabId=SecurityLinkID&lt;/a&gt; and also under the Properties tab in Home &lt;a title="http://localhost/Reports_SQL2008/Pages/Folder.aspx?SelectedTabId=PropertiesTab" href="http://localhost/Reports_SQL2008/Pages/Folder.aspx?SelectedTabId=PropertiesTab"&gt;http://localhost/Reports_SQL2008/Pages/Folder.aspx?SelectedTabId=PropertiesTab&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Calling the API&lt;/h4&gt;  &lt;p&gt;This post is mainly about solving some of the problems you may face, for detailed information on calling the API check out MSDN which has a wealth of information on the topic, here is the &lt;a href="http://msdn.microsoft.com/en-us/library/ms152787(SQL.90).aspx" target="_blank"&gt;Overview&lt;/a&gt; and more specifically how to &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.wssux.reportingserviceswebservice.rsexecutionservice2005.reportexecutionservice.render(SQL.90).aspx" target="_blank"&gt;Render a Report&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;However note that you may have to pass a TrustedUserHeader type whenever calling a Web Service method, it’s ok for this value to be Null. &lt;/p&gt;  &lt;h4&gt;WCF Security&lt;/h4&gt;  &lt;p&gt;Once you’ve followed the guide and coded your solution appropriately you may come across this exception or one similar when trying to call a Web Service method. &lt;/p&gt;  &lt;h4&gt;&lt;font size="2"&gt;The authentication header received from the server was 'Negotiate,NTLM'.&lt;/font&gt;&lt;/h4&gt;  &lt;p&gt;The key here is to set the Network Credential property before to a Windows user who has access to the Reports and has the correct Role Assignments in the Report Manager. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;rsClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ReportExecutionServiceSoapClient&lt;/span&gt;(); 

            rsClient.ClientCredentials.Windows
                .ClientCredential = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NetworkCredential&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;);
            rsClient.ClientCredentials.Windows
                .AllowedImpersonationLevel = System.Security.Principal.&lt;span style="color: #2b91af"&gt;TokenImpersonationLevel&lt;/span&gt;.Impersonation;
            &lt;/pre&gt;

&lt;p&gt;Also make sure that in the Web.Config in C:\Program Files\Microsoft SQL Server\MSRS10.SQL2008\Reporting\Services\ReportServer has the following values set. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160; &amp;lt;authentication mode=&amp;quot;Windows&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;identity impersonate=&amp;quot;true&amp;quot; /&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are the bindings I use and work well. Make sure to set all the properties to the Maximum allowed values as Report Server returns some fairly large arrays.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;bindings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;binding &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ReportExecutionServiceSoap&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;closeTimeout&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;00:01:00&lt;/span&gt;&amp;quot;
            &lt;span style="color: red"&gt;openTimeout&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;00:01:00&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;receiveTimeout&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;00:10:00&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;sendTimeout&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;00:01:00&lt;/span&gt;&amp;quot;
            &lt;span style="color: red"&gt;allowCookies&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;bypassProxyOnLocal&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;hostNameComparisonMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;StrongWildcard&lt;/span&gt;&amp;quot;
            &lt;span style="color: red"&gt;maxBufferSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;65536&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;maxBufferPoolSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;65536&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;maxReceivedMessageSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;65536&lt;/span&gt;&amp;quot;
            &lt;span style="color: red"&gt;messageEncoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Text&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;textEncoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;transferMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Buffered&lt;/span&gt;&amp;quot;
            &lt;span style="color: red"&gt;useDefaultWebProxy&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;readerQuotas &lt;/span&gt;&lt;span style="color: red"&gt;maxDepth&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;2147483647&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;maxStringContentLength&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;2147483647&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;maxArrayLength&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;2147483647&lt;/span&gt;&amp;quot;
              &lt;span style="color: red"&gt;maxBytesPerRead&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;2147483647&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;maxNameTableCharCount&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;2147483647&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;security &lt;/span&gt;&lt;span style="color: red"&gt;mode&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;TransportCredentialOnly&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;transport &lt;/span&gt;&lt;span style="color: red"&gt;clientCredentialType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Ntlm&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;proxyCredentialType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;None&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;realm&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;message &lt;/span&gt;&lt;span style="color: red"&gt;clientCredentialType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;UserName&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;algorithmSuite&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Default&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
          &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;security&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;binding&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;bindings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;client&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;endpoint &lt;/span&gt;&lt;span style="color: red"&gt;address&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;http://localhost/ReportServer_SQL2008/ReportExecution2005.asmx&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;binding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;basicHttpBinding&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ReportExecutionServiceSoap&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;contract&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Services.Impl.ReportExecution2005.ReportExecutionServiceSoap&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ReportExecutionServiceSoap&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;client&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Conclusion &lt;/h4&gt;

&lt;p&gt;I’m all about using the right tool for the job so for Reporting when you’re using SQL Server 2008 as your data store you really can’t go past SSRS which even comes free with SQL Server Express Edition. &lt;/p&gt;

&lt;p&gt;Also included in SSRS 2008 is the &lt;a href="http://msdn.microsoft.com/en-us/library/ms155933.aspx" target="_blank"&gt;Report Builder&lt;/a&gt; which is a Report Designer tool accessible from the Report Manager allowing users to design reports without having to install the Business Intelligence Studio. &lt;/p&gt;

&lt;p&gt;Hope this helps someone.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/CYMp5QM1vcY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/CYMp5QM1vcY/consuming-ssrs-reportexecutionservice.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/11/consuming-ssrs-reportexecutionservice.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-8704380405252007908</guid><pubDate>Tue, 05 Oct 2010 13:00:00 +0000</pubDate><atom:updated>2010-10-05T21:00:02.278+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">c#</category><title>SharpKit C# to Javascript Convertor</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Recently I discovered &lt;a href="http://sharpkit.net/" target="_blank"&gt;SharpKit&lt;/a&gt; whilst looking at an online IDE called &lt;a href="http://www.coderun.com" target="_blank"&gt;CodeRun&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;SharpKit is described as “a Web Toolkit that enables you to write C# and convert it to JavaScript during compilation.”&lt;/p&gt;  &lt;p&gt;There are a number of other similar tools around that try and achieve the goal of writing in a Static language and then converting it to JavaScript.&lt;/p&gt;  &lt;p&gt;Some of those include:&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://code.google.com/webtoolkit/" target="_blank"&gt;GWT&lt;/a&gt; (Google Web Toolkit) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://projects.nikhilk.net/ScriptSharp" target="_blank"&gt;Script #&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jsc.sourceforge.net/" target="_blank"&gt;jsc&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I can’t speak for jsc or Script # but I’ve had a good look at GWT and although I can see the benefits it reminded me a bit of the ASP.NET WebForms model in that the high level of abstraction has a big learning curve. &lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;SharpKit&lt;/strong&gt; &lt;a href="http://sharpkit.net/overview/features/" target="_blank"&gt;feature list&lt;/a&gt; is very impressive. &lt;/p&gt;  &lt;p&gt;This is the first time I have tried SharpKit so I’m going to do a very simple walkthrough and how to get started. &lt;/p&gt;  &lt;h4&gt;Installation&lt;/h4&gt;  &lt;p&gt;Grab the Download from the &lt;a href="http://sharpkit.net/download/" target="_blank"&gt;SharpKit website&lt;/a&gt; and run the Installer. &lt;/p&gt;  &lt;p&gt;As &lt;strong&gt;SharpKit&lt;/strong&gt; is a commercial product they require you to Register before Downloading, but don’t be put off by this. &lt;/p&gt;  &lt;p&gt;After installing you will get the following folders. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;C:\Program Files\SharpKit\Addin &lt;/li&gt;    &lt;li&gt;C:\Program Files\SharpKit\Assemblies &lt;/li&gt;    &lt;li&gt;C:\Program Files\SharpKit\Samples &lt;/li&gt;    &lt;li&gt;C:\Program Files\SharpKit\Templates &lt;/li&gt;    &lt;li&gt;C:\Program Files\SharpKit\Utils &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The &lt;strong&gt;Samples&lt;/strong&gt; folder contains really good examples of each project type so is the best way to get started. &lt;/p&gt;  &lt;h4&gt;Project Structure&lt;/h4&gt;  &lt;p&gt;In my ignorance I assumed that you could just reference the DLLs and away you go, however this was an incorrect assumption. You actually have to use one of the &lt;strong&gt;SharpKit&lt;/strong&gt; Visual Studio project templates. &lt;/p&gt;  &lt;p&gt;I really don’t like this and would expect that there should be a Command-Line interface that you can call in the Post-Build event to do the conversion. Correct me if I’m wrong but I couldn’t find any such Utility. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/TKsbIny0_nI/AAAAAAAAAYg/GoFnuzFF8F8/s1600-h/sharpkit_projects3.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="sharpkit_projects" border="0" alt="sharpkit_projects" src="http://lh3.ggpht.com/_la3Rv-0jOCI/TKsbJdkCVRI/AAAAAAAAAYk/6tSrDtMNncI/sharpkit_projects_thumb1.jpg?imgmax=800" width="710" height="521" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Defining the Class &lt;/h4&gt;  &lt;p&gt;When you create a class that you want to be exported to JavaScript you have to annotate it with the &lt;a href="http://sharpkit.net/help/index.html" target="_blank"&gt;JsType attribute&lt;/a&gt;. This defines how you want the Class to be converted at Build-Time. &lt;/p&gt;  &lt;p&gt;There are 4 distinct modes you can use&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CLR – Adds .NET Support to the Client including LINQ &lt;/li&gt;    &lt;li&gt;Global – Exports all function as global static functions &lt;/li&gt;    &lt;li&gt;JSON – Not exported but treats as a JSON object when instantiated &lt;/li&gt;    &lt;li&gt;Prototype – Exported as a function with an instance constructor &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you want to use &lt;strong&gt;jQuery&lt;/strong&gt; then you need to inherit from &lt;strong&gt;jQueryContext. &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The other 3rd party libraries following the same pattern and inheriting a base class.&lt;/p&gt;  &lt;p&gt;Below is a simple example: &lt;/p&gt;  &lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;JsType&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;JsMode&lt;/span&gt;.Global, &lt;span style="color: #a31515"&gt;&amp;quot;common.js&amp;quot;&lt;/span&gt;)]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;common &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;jQueryContext
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public static void &lt;/span&gt;btn_click()
        {
            jQuery(&lt;span style="color: #a31515"&gt;&amp;quot;#div1&amp;quot;&lt;/span&gt;).show(1000, onShowEnded); 
        }
        &lt;span style="color: blue"&gt;static void &lt;/span&gt;onShowEnded()
        {
            jQuery(&lt;span style="color: #a31515"&gt;&amp;quot;#div1&amp;quot;&lt;/span&gt;).css(&lt;span style="color: #a31515"&gt;&amp;quot;color&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;); 
        }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see that you have to specify the physical name of the file in the JSType Attribute and the file will be generated relative to where the CSharp file is located. &lt;/p&gt;

&lt;p&gt;The generated JavaScript for the above class looks like this: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//@AutoGenerated
&lt;/span&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;btn_click()
{
    $(&lt;span style="color: #a31515"&gt;&amp;quot;#div1&amp;quot;&lt;/span&gt;).show(1000, onShowEnded);
}
&lt;span style="color: blue"&gt;function &lt;/span&gt;onShowEnded()
{
    $(&lt;span style="color: #a31515"&gt;&amp;quot;#div1&amp;quot;&lt;/span&gt;).css(&lt;span style="color: #a31515"&gt;&amp;quot;color&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;The code that’s generated is of a high standard. There’s not much else to show you on this as it’s fairly self-explanatory, check out the &lt;a href="http://sharpkit.net/howto/" target="_blank"&gt;How-Tos&lt;/a&gt; for more detailed information.&lt;/p&gt;

&lt;h4&gt;3rd Party Library Support&lt;/h4&gt;

&lt;p&gt;Whilst you can use &lt;strong&gt;SharpKit&lt;/strong&gt; to write raw JavaScript there’s not a lot of point these days with so many great libraries around. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SharpKit&lt;/strong&gt; comes with very comprehensive support for Libraries and currently supports the follwing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;jQuery &lt;/li&gt;

  &lt;li&gt;jQTouch &lt;/li&gt;

  &lt;li&gt;jQuery UI &lt;/li&gt;

  &lt;li&gt;YUI &lt;/li&gt;

  &lt;li&gt;ExtJS &lt;/li&gt;

  &lt;li&gt;GoogleMaps &lt;/li&gt;

  &lt;li&gt;ASP.NET AJAX &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s yet to be seen how they manage to keep up with library changes. &lt;/p&gt;

&lt;h4&gt;Pricing&lt;/h4&gt;

&lt;p&gt;At the time of writing they have a &lt;a href="http://en.wikipedia.org/wiki/Freemium" target="_blank"&gt;Freemium&lt;/a&gt; pricing model. &lt;/p&gt;

&lt;p&gt;SharpKit Lite – Free version with a limit of 1000 lines of code 
  &lt;br /&gt;SharpKit Pro - $649 / Developer&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Having a free version is good but if you’re considering a Tool of this sort at all then it’s likely you’re doing some heavy JavaScript development so will very quickly go over 1000 LOC. &lt;/p&gt;

&lt;p&gt;At $649 I think it is pretty good value, however it would likely be too much for lone developers or Open Source projects. 
  &lt;br /&gt;What would be nice is an Open Source Project License which is heavily discounted or better yet free. This could be combined with an affiliate badge linking back to &lt;strong&gt;SharpKit&lt;/strong&gt; that you need to display on your website, similar to &lt;strong&gt;Kentico&lt;/strong&gt;.&amp;#160; &lt;/p&gt;

&lt;h4&gt;Pros&lt;/h4&gt;

&lt;p&gt;All in all I was pretty impressed with this Tool and it shows great promise. Here’s what I think are good about it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Comprehensive 3rd Party Library support &lt;/li&gt;

  &lt;li&gt;.NET CLR Support &lt;/li&gt;

  &lt;li&gt;Good Documentation &amp;amp; Support &lt;/li&gt;

  &lt;li&gt;Generates Clean JavaScript Code &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Cons&lt;/h4&gt;

&lt;p&gt;However there were a few things I do not like about it. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Forced to use the SharpKit Visual Studio Project Template &lt;/li&gt;

  &lt;li&gt;No Visual Studio 2010 Support &lt;/li&gt;

  &lt;li&gt;Pricing &lt;/li&gt;

  &lt;li&gt;Heavy use of Attributes &lt;/li&gt;

  &lt;li&gt;No Command-Line tool to perform the conversion &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;As a Software Architect I’ve never been able to decide on the best way for JavaScript to be organized in Web Projects and usually leave it up to the Lead Web Developer who’s going to be working with it on a daily basis. &lt;/p&gt;

&lt;p&gt;However this inevitably leads to lot’s of scattered JavaScript throughout the project and it quickly becomes a maintenance headache. &lt;/p&gt;

&lt;p&gt;So to me the idea of writing C# and have it converted to JavaScript at build-time is very attractive indeed from both a maintenance and testability point of view. However I’m thinking that in practice it’s only really going to help .NET Developers with basic JavaScript knowledge as more advanced JavaScript developers would feel highly constrained by losing the Dynamic goodness of the language. &lt;/p&gt;

&lt;p&gt;For those reasons I’m not entirely sold on &lt;strong&gt;SharpKit&lt;/strong&gt; and similar tools just yet, however it’s definitely worth investigating further and I’m probably going to use this on the next piece of non-trivial JavaScript that needs writing. 

  &lt;br /&gt;Stay tuned for more on that. &lt;/p&gt;

&lt;p&gt;I’m keen to know your thoughts on this and similar tools, so feel free to comment. &lt;/p&gt;

&lt;p&gt;Till next time.&amp;#160; &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/gw3pbzvSkKQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/gw3pbzvSkKQ/sharpkit-c-to-javascript-convertor.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_la3Rv-0jOCI/TKsbJdkCVRI/AAAAAAAAAYk/6tSrDtMNncI/s72-c/sharpkit_projects_thumb1.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/10/sharpkit-c-to-javascript-convertor.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-3062936789013855162</guid><pubDate>Tue, 28 Sep 2010 13:00:00 +0000</pubDate><atom:updated>2010-09-28T21:00:05.761+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">c#</category><title>Invoking System.Actions with Retries using ReliableActionInvoker</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Although some would argue that Exceptions should be thrown and handled one level up. I tend to think there are plenty of cases where by after an Exception is thrown it makes total sense to Retry the operation N number of times before finally Re-throwing the Exception up the Call stack. &lt;/p&gt; &lt;p&gt;One of these such cases is the simple act of Downloading a file from a Remote Server. Although the code is very simple, &lt;strong&gt;WebClient.DownloadFile&lt;/strong&gt;&amp;nbsp; can and does fail frequently for a host of different reasons. &lt;/p&gt; &lt;p&gt;Consider the following example which simply tries to download a remote Uri to a local file path. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        private int &lt;/span&gt;maxRetries = 5;
        &lt;span style="color: blue"&gt;private int &lt;/span&gt;retriesCounter;

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Download(&lt;span style="color: blue"&gt;string &lt;/span&gt;uri, &lt;span style="color: blue"&gt;string &lt;/span&gt;targetFilePath)
        {
            &lt;span style="color: blue"&gt;try
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;var &lt;/span&gt;webClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();

                webClient.DownloadFile(uri, targetFilePath);

                retriesCounter = 0; 
            }
            &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;WebException &lt;/span&gt;webEx)
            {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(retriesCounter &amp;gt;= maxRetries)
                {
                    &lt;span style="color: blue"&gt;throw&lt;/span&gt;;
                }

                retriesCounter++;

                Download(uri, targetFilePath);
            }

        }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;As you can see with a little bit of Recursion we retry the Operation a maximum of 5 times and then finally Throw the exception. &lt;/p&gt;
&lt;p&gt;This type of code is messy to read, very repetitive and also common to errors which can lead to the dreaded &lt;strong&gt;StackOverflowException.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To get around this I’ve come up with what I call a &lt;strong&gt;ReliableActionInvoker &lt;/strong&gt;which essentially provides a generic way to Invoke System.Actions and retry them if any Exception or an explicit Exception occurs. &lt;/p&gt;
&lt;h4&gt;Interface&lt;/h4&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IReliableActionInvoker
   &lt;/span&gt;{
       &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
       /// &lt;/span&gt;&lt;span style="color: green"&gt;Tries to Invoke the supplied action and if any Exception is thrown will
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;retry the number of times supplied as maxRetries
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
       /// &amp;lt;param name="action"&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;param name="maxRetries"&amp;gt;&amp;lt;/param&amp;gt;
       &lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;Invoke(System.&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries);

       &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
       /// &lt;/span&gt;&lt;span style="color: green"&gt;Tries to Invoke the supplied Action and if the Exception is of the 
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;supplied ExceptionType will retry the number of times supplied as 
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;maxRetries
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
       /// &amp;lt;param name="action"&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;param name="maxRetries"&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;param name="exceptionType"&amp;gt;&amp;lt;/param&amp;gt;
       &lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;Invoke(System.&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries, &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;exceptionType);

       &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
       /// &lt;/span&gt;&lt;span style="color: green"&gt;Tries to Invoke the supplied Action and if the Action throws
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;an Exception that is contained in the supplied exceptionTypes array
       &lt;/span&gt;&lt;span style="color: gray"&gt;///  &lt;/span&gt;&lt;span style="color: green"&gt;will retry the number of times supplied as maxRetries
       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
       /// &amp;lt;param name="action"&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;param name="maxRetries"&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;param name="exceptionTypes"&amp;gt;&amp;lt;/param&amp;gt;
       &lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;Invoke(System.&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] exceptionTypes);
   }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;If you’re not familiar with &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx" target="_blank"&gt;System.Action&lt;/a&gt; then I suggest you &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx" target="_blank"&gt;check it out on MSDN&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Implementation&lt;/h4&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ReliableActionInvoker &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IReliableActionInvoker
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private int &lt;/span&gt;retriesCounter;
&lt;span style="color: blue"&gt;        public void &lt;/span&gt;Invoke(&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;exceptionTypes = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[0];

            Invoke(action, maxRetries, exceptionTypes);
        }

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Invoke(&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries, &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;exceptionType)
        {
            Invoke(action, maxRetries, &lt;span style="color: blue"&gt;new&lt;/span&gt;[] {exceptionType});
        }

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Invoke(&lt;span style="color: #2b91af"&gt;Action &lt;/span&gt;action, &lt;span style="color: blue"&gt;int &lt;/span&gt;maxRetries, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] exceptionTypes)
        {
            &lt;span style="color: blue"&gt;try
            &lt;/span&gt;{
                action.Invoke();
                retriesCounter = 0; 
            }
            &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;ex)
            {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(retriesCounter &amp;gt;= maxRetries)
                {
                    retriesCounter = 0; 
                    &lt;span style="color: blue"&gt;throw&lt;/span&gt;; 
                }
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(exceptionTypes == &lt;span style="color: blue"&gt;null &lt;/span&gt;|| exceptionTypes.Length == 0)
                {
                    retriesCounter++;
                    Invoke(action, maxRetries, exceptionTypes);
                    &lt;span style="color: blue"&gt;return&lt;/span&gt;;
                }

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(exceptionTypes.Contains(ex.GetType()))
                {
                    retriesCounter++;
                    Invoke(action, maxRetries, exceptionTypes);
                    &lt;span style="color: blue"&gt;return&lt;/span&gt;;
                }

                &lt;span style="color: blue"&gt;throw&lt;/span&gt;;
            }
        }

  }&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This code is pretty self explanatory. I first call &lt;strong&gt;Action.Invoke &lt;/strong&gt;and catch the Exception. When no Exception Type is supplied then Retry, otherwise check if the caught Exception exists in the supplied Collection and Retry. &lt;/p&gt;
&lt;p&gt;When the maxRetries has been reached Throw the Exception. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Usage&lt;/h4&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClientDownloader &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IUriDownloader
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IReliableActionInvoker &lt;/span&gt;reliableActionInvoker;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;WebClientDownloader(&lt;span style="color: #2b91af"&gt;IReliableActionInvoker &lt;/span&gt;reliableActionInvoker)
        {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.reliableActionInvoker = reliableActionInvoker;
        }

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Download(&lt;span style="color: blue"&gt;string &lt;/span&gt;uri, &lt;span style="color: blue"&gt;string &lt;/span&gt;targetFilePath)
        {
            uri.ValidateArgumentNull();
            targetFilePath.ValidateArgumentNull(); 

            &lt;span style="color: blue"&gt;var &lt;/span&gt;webClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebClient&lt;/span&gt;();

            reliableActionInvoker
                .Invoke(() =&amp;gt; webClient.DownloadFile(uri, targetFilePath), 5, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;WebException&lt;/span&gt;));
        }

    }
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Finally here’s how you could use it. &lt;/p&gt;
&lt;p&gt;That’s all there is to it, it’s pretty simple really. I’m keen here to what you think or how you’ve approached this problem in a generic way before so feel free to comment.&lt;/p&gt;
&lt;p&gt;The nice thing about this is it opens up the possibility to implement this using AOP but I’ll leave that to another post.&lt;/p&gt;
&lt;p&gt;Till next time.&amp;nbsp; &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/9_kRB1iBbJE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/9_kRB1iBbJE/invoking-systemactions-with-retries.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/invoking-systemactions-with-retries.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-7493686170261249134</guid><pubDate>Tue, 21 Sep 2010 13:00:00 +0000</pubDate><atom:updated>2010-09-21T21:00:06.169+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">rest</category><category domain="http://www.blogger.com/atom/ns#">openrasta</category><category domain="http://www.blogger.com/atom/ns#">mvc</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">wcf</category><title>OpenRasta vs WCF for RESTful Services</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Not long ago I discovered &lt;a href="http://openrasta.com/" target="_blank"&gt;OpenRasta&lt;/a&gt;. If you’re not familiar with it it’s described as a “resource-oriented framework for .NET enabling easy ReST-ful development of websites and services”.&lt;/p&gt;  &lt;p&gt;After reading &lt;a href="http://rails-nutshell.labs.oreilly.com/" target="_blank"&gt;Rails 3 in a Nutshell&lt;/a&gt; I started looking at .NET a bit differently and have started being envious of the simplicity of Rails. When it comes to REST the ROR guys have definitely approached it the right way and it is &lt;a href="http://rails-nutshell.labs.oreilly.com/ch07.html" target="_blank"&gt;baked right into the Rails framework.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When it comes to .NET there are a few different approaches you can take to create RESTful services.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ASP.NET MVC &lt;/li&gt;    &lt;li&gt;WCF &lt;/li&gt;    &lt;li&gt;OpenRasta &lt;/li&gt;    &lt;li&gt;Other MVC Frameworks &lt;/li&gt;    &lt;li&gt;Standard HTTP Handlers &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this post I’m going to cover how you can implement such a service using WCF and OpenRasta.&lt;/p&gt;  &lt;p&gt;The goal is to expose a Product as JSON and XML using a RESTful uri.    &lt;br /&gt;    &lt;br /&gt;product/1 &lt;/p&gt;  &lt;h2&gt;WCF Approach&lt;/h2&gt;  &lt;p&gt;First let’s have a look at how to do this in WCF&lt;/p&gt;  &lt;h4&gt;Project Structure &lt;/h4&gt;  &lt;p&gt;Just create a standard WCF Service Application Project&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TJQ3gEM0bzI/AAAAAAAAAYQ/eiuYN6Hr5A8/s1600-h/wcfproject%5B2%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="wcfproject" border="0" alt="wcfproject" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TJQ3gkMu_wI/AAAAAAAAAYU/5SB6t3DrLmE/wcfproject_thumb.jpg?imgmax=800" width="244" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;DataContract&lt;/h4&gt;  &lt;p&gt;The first thing we have to do is create a DataContract which is just a Data Transfer Object that you want to be exposed by the web service. &lt;/p&gt;  &lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;DataContract&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public int &lt;/span&gt;Id { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

        [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You have to annotate the class with the &lt;strong&gt;DataContract&lt;/strong&gt; attribute and properties with the &lt;strong&gt;DataMember&lt;/strong&gt; attribute. &lt;/p&gt;

&lt;h4&gt;Service Contract&lt;/h4&gt;

&lt;p&gt;Now we have to define our Service Contract. &lt;/p&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;ServiceContract&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICatalogService
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]
        [&lt;span style="color: #2b91af"&gt;WebGet&lt;/span&gt;(UriTemplate = &lt;span style="color: #a31515"&gt;&amp;quot;product/{id}&amp;quot;&lt;/span&gt;, ResponseFormat = &lt;span style="color: #2b91af"&gt;WebMessageFormat&lt;/span&gt;.Json)]
        &lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;GetProductById(&lt;span style="color: blue"&gt;string &lt;/span&gt;id);

    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The important part here is the&lt;strong&gt; WebGet&lt;/strong&gt; attribute. The &lt;strong&gt;UriTemplate&lt;/strong&gt; specifies the route which you can access the Resource on and the&lt;strong&gt; ResponseFormat&lt;/strong&gt; specifies the format or Content-Type to return the resource as, you can choose from Json or XML. &lt;/p&gt;

&lt;p&gt;Having to limit to a single Content-Type is already a serious limitation and the &lt;strong&gt;UriTemplate&lt;/strong&gt; being an attribute property makes it hard to change this route easily. &lt;/p&gt;

&lt;p&gt;Also notice that the Id argument is a string, this is deliberate as the &lt;strong&gt;UriTemplate&lt;/strong&gt; only supports having path segments of type string. If you try otherwise you will see an exception similar to below. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Operation 'GetProductById' in contract 'ICatalogService' has a path variable named 'id' which does not have type 'string'.&amp;#160; Variables for UriTemplate path segments must have type 'string'.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;Service Implementation&lt;/h4&gt;

&lt;p&gt;Next we go to the Service implementation, this is pretty standard. &lt;/p&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(RequirementsMode= &lt;span style="color: #2b91af"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Allowed)]
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CatalogService &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ICatalogService
    &lt;/span&gt;{
       
        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;GetProductById(&lt;span style="color: blue"&gt;int &lt;/span&gt;id)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{ Name = &lt;span style="color: #a31515"&gt;&amp;quot;WCF&amp;quot;&lt;/span&gt;, Id = 1 };

            &lt;span style="color: blue"&gt;return &lt;/span&gt;product; 
        }

     }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The only difference here from a standard service implementation is the use of the &lt;strong&gt;AspNetCompatibilityRequirements &lt;/strong&gt;attribute on the class. &lt;/p&gt;

&lt;h4&gt;Web.Config&lt;/h4&gt;

&lt;p&gt;The only additional config required is the standardEndpoints configuration. The full config is below. &lt;/p&gt;

&lt;pre class="code"&gt; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;standardEndpoints&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;webHttpEndpoint&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;standardEndpoint &lt;/span&gt;&lt;span style="color: red"&gt;defaultOutgoingResponseFormat&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Json&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&amp;quot; &lt;span style="color: red"&gt;helpEnabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;automaticFormatSelectionEnabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;webHttpEndpoint&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;standardEndpoints&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;behaviors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;behavior&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceMetadata &lt;/span&gt;&lt;span style="color: red"&gt;httpGetEnabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceDebug &lt;/span&gt;&lt;span style="color: red"&gt;includeExceptionDetailInFaults&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;behavior&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;behaviors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceHostingEnvironment &lt;/span&gt;&lt;span style="color: red"&gt;multipleSiteBindingsEnabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Consuming the Service&lt;/h4&gt;

&lt;p&gt;For the service to return JSON you have to specify in the Content-Type as &amp;quot;&lt;strong&gt;application/json” &lt;/strong&gt;in the HTTP Header, for XML use &lt;strong&gt;application/xml.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can consume using URI &lt;a href="http://myrestsite.com/CatalogService.svc/product/1"&gt;http://myrestsite.com/CatalogService.svc/product/1&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Observations&lt;/h4&gt;

&lt;p&gt;Ok well that wasn’t so bad, however I’m sure you’ve already identified a few limitations. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Inflexible routing options, only one Uri per method &lt;/li&gt;

  &lt;li&gt;Only able to return XML or JSON &lt;/li&gt;

  &lt;li&gt;Heavy use of Attributes &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;OpenRasta Approach&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://openrasta.com/" target="_blank"&gt;OpenRasta&lt;/a&gt; deal with Resources, Handlers and Views, but we aren’t concerned with Views in this post. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handlers&lt;/strong&gt; 

  &lt;br /&gt;”Handlers are the objects responsible to act upon resources through the HTTP uniform interface and will always get called first. They're the equivalent of Controllers in other MVC frameworks.”&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;strong&gt;Resources 
    &lt;br /&gt;&lt;/strong&gt;”Your resources are what you expose on various Uris. In OpenRasta, each thing you want to expose on the web needs to have a Resource class associated with it.”&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Project Structure&lt;/h4&gt;

&lt;p&gt;To host OpenRasta you need to create a standard Web Application project but your Resources and Handlers can be contained in a standard Class Library project. &lt;/p&gt;

&lt;p&gt;After installing &lt;a href="http://www.ohloh.net/p/openrasta/download?filename=OpenRasta-2.0.3214.437.exe" target="_blank"&gt;OpenRasta&lt;/a&gt; you’ll need to add references to the following DLLs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;OpenRasta.dll &lt;/li&gt;

  &lt;li&gt;OpenRasta.Codecs.WebForms.dll &lt;/li&gt;

  &lt;li&gt;OpenRasta.Hosting.AspNet.dll &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project structure is very simple, you can split it into Handlers and Resources as shown below. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_la3Rv-0jOCI/TJQ3iQ7rY9I/AAAAAAAAAYY/bgn70abNmvs/s1600-h/openrastaproject%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="openrastaproject" border="0" alt="openrastaproject" src="http://lh3.ggpht.com/_la3Rv-0jOCI/TJQ3i7BHcxI/AAAAAAAAAYc/xCGu1J8KOWw/openrastaproject_thumb%5B1%5D.jpg?imgmax=800" width="244" height="170" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;Resource&lt;/h4&gt;

&lt;p&gt;The Resource or DTO is just a standard POCO. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;public int &lt;/span&gt;Id { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }

       &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice there’s no base class to inherit or any attributes. This is important as it makes it very easy to utilise Classes that you already have defined. &lt;/p&gt;

&lt;h4&gt;Handler&lt;/h4&gt;

&lt;p&gt;Handlers are equivalent to MVC Controllers or compared with WCF it’s the Service implementation. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProductHandler
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public object &lt;/span&gt;Get(&lt;span style="color: blue"&gt;int &lt;/span&gt;id)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;product = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;{Name = &lt;span style="color: #a31515"&gt;&amp;quot;OpenRasta&amp;quot;&lt;/span&gt;, Id = 1};

            &lt;span style="color: blue"&gt;return &lt;/span&gt;product;
        }
    }&lt;/pre&gt;

&lt;p&gt;Again no base class or attributes required.&lt;/p&gt;

&lt;h4&gt;OpenRasta Config&lt;/h4&gt;

&lt;p&gt;One of the great things about OpenRasta is that the Configuration of how the Resources are accessed is completely decoupled from the implementation. The configuration has a nice fluent interface for configuring Handlers and Resources. &lt;/p&gt;

&lt;p&gt;You can create a class with any name and implement the &lt;strong&gt;OpenRasta.Configuration.IConfigurationSource &lt;/strong&gt;interface&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OpenRastaConfig &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IConfigurationSource
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;#region &lt;/span&gt;IConfigurationSource Members

       &lt;span style="color: blue"&gt;public void &lt;/span&gt;Configure()
       {
           &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;OpenRastaConfiguration&lt;/span&gt;.Manual)
           {
               &lt;span style="color: #2b91af"&gt;ResourceSpace&lt;/span&gt;.Has.ResourcesOfType&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;()
                   .AtUri(&lt;span style="color: #a31515"&gt;&amp;quot;/product/{id}&amp;quot;&lt;/span&gt;)
                   .HandledBy&amp;lt;&lt;span style="color: #2b91af"&gt;ProductHandler&lt;/span&gt;&amp;gt;()
                   .AsJsonDataContract()
                   .And
                   .AsXmlDataContract();
           }
       }

       &lt;span style="color: blue"&gt;#endregion
   &lt;/span&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;p&gt;.AtUri specifies the Uri you can use to access the Resource. It’s also possible to have multiple Uris for the same resource.&lt;/p&gt;

&lt;pre class="code"&gt;                    .AtUri(&lt;span style="color: #a31515"&gt;&amp;quot;/product/{id}&amp;quot;&lt;/span&gt;)
                    .And
                    .AtUri(&lt;span style="color: #a31515"&gt;&amp;quot;/products/{id}&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;.HandledBy&amp;lt;ProductHandler&amp;gt;&lt;/strong&gt; specifies the Handler to use. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.AsJsonDataContract()&lt;/strong&gt; tells OpenRasta you want to expose the resource as Json&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.AsXmlDataContract()&lt;/strong&gt; tells OpenRasta you want to expose the resource as Xml&lt;/p&gt;

&lt;h4&gt;Web.Config&lt;/h4&gt;

&lt;p&gt;There is a little bit of Web.Config configuration to be done as well, this is all you need:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;compilation &lt;/span&gt;&lt;span style="color: red"&gt;debug&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;targetFramework&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;4.0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;verb&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;*&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;path&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;*.rastahook&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRasta.Hosting.AspNet.OpenRastaHandler, OpenRasta.Hosting.AspNet&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;httpModules&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRastaModule&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRasta.Hosting.AspNet.OpenRastaModule, OpenRasta.Hosting.AspNet&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;httpModules&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.webServer&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;validation &lt;/span&gt;&lt;span style="color: red"&gt;validateIntegratedModeConfiguration&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;modules&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRastaModule&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRasta.Hosting.AspNet.OpenRastaModule, OpenRasta.Hosting.AspNet&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;modules&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;handlers&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRastaHandler&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;verb&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;*&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;path&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;*.rastahook&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;OpenRasta.Hosting.AspNet.OpenRastaHandler, OpenRasta.Hosting.AspNet&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;handlers&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.webServer&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&lt;/span&gt;&lt;/pre&gt;

&lt;h4&gt;Consuming the Service&lt;/h4&gt;

&lt;p&gt;As with WCF you need to specify the correct Content-Type to get the format you desire. &lt;/p&gt;

&lt;p&gt;You can consume using a URI like &lt;a href="http://myrestsite.com/product/1"&gt;http://myrestsite.com/product/1&lt;/a&gt; or &lt;a href="http://myrestsite.com/products/1"&gt;http://myrestsite.com/products/1&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Observations&lt;/h4&gt;

&lt;p&gt;All in all OpenRasta is a nicer development experience and is more closely tied to the definition of REST. It is fully extensible and allows to return a Resource in any Format, including an HTML View. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I’ve only touched on a very basic use of OpenRasta, it has tons more functionality which makes developing RESTful services a breeze and also stacks up as a very good MVC framework if you’re having issues with the ASP.NET implementation. It has pretty good documentation and a strong community around it. &lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="http://trac.caffeine-it.com/openrasta/wiki/Doc" target="_blank"&gt;Comparisons table&lt;/a&gt; for a round up of features.&lt;/p&gt;

&lt;p&gt;IMO doing REST in WCF just doesn’t seem very intuitive to me and is much less flexible especially when you dive deep into using HTTP Status Codes and HTTP Verbs. &lt;/p&gt;

&lt;p&gt;If you have a requirement to develop a RESTful service instead of defaulting to WCF I urge you consider OpenRasta instead. &lt;/p&gt;

&lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/1dRBzHxc7J0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/1dRBzHxc7J0/openrasta-vs-wcf-for-restful-services.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_la3Rv-0jOCI/TJQ3gkMu_wI/AAAAAAAAAYU/5SB6t3DrLmE/s72-c/wcfproject_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/openrasta-vs-wcf-for-restful-services.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-9189221887764276720</guid><pubDate>Tue, 14 Sep 2010 13:06:00 +0000</pubDate><atom:updated>2010-09-14T21:07:48.372+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">net</category><title>Defensive Programming &amp; Argument Validation</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The other day I found myself debugging the dreaded &lt;strong&gt;NullReferenceException &lt;/strong&gt;“Object Reference not set to an instance of an object” on a piece of code written by a fairly Senior Developer. &lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you’ve been developing on .NET for more than 5 minutes then I’m sure you have come across this in your daily work and it is incredibly frustrating to try and debug. &lt;/p&gt;  &lt;p&gt;With this post I hope to demonstrate how by using Defensive Programming you can make your API’s more robust and as a result reduce the number of bugs in your code.    &lt;br /&gt;    &lt;br /&gt;If you’re a bit hazy on Defensive Programming and it’s cousins then I suggest you read the following:&lt;/p&gt; &lt;a href="http://en.wikipedia.org/wiki/Defensive_programming" target="_blank"&gt;Defensive Programming&lt;/a&gt;   &lt;br /&gt;&lt;a href="http://c2.com/cgi/wiki?FailFast" target="_blank"&gt;Fail Fast&lt;/a&gt;   &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_by_contract" target="_blank"&gt;Design by Contract (DbC)&lt;/a&gt;   &lt;p&gt;Validating method arguments for public methods&lt;strong&gt; should&lt;/strong&gt; be a very simple concept to grasp and for most skilled developers is a&amp;#160; as natural as writing If statements. &lt;/p&gt;  &lt;p&gt;The guiding principle I follow is to trust no single input and ensure that code only executes when the supplied arguments satisfy the requirements (pre-conditions). If it does not it should Fail Fast and throw an exception.&lt;/p&gt;  &lt;h4&gt;Take One&lt;/h4&gt;  &lt;p&gt;Here’s an example of what I consider to be a poorly written method.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;ChangeProductName(&lt;span style="color: blue"&gt;int &lt;/span&gt;productId, &lt;span style="color: blue"&gt;string &lt;/span&gt;name)
        {
            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;uow = uowFactory.Create())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;product = productRepository.Get(productId);

                product.ChangeName(name); 

                uow.Commit(); 
            }

            &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;{WasSuccessful = &lt;span style="color: blue"&gt;true&lt;/span&gt;}; 
        }&lt;/pre&gt;

&lt;p&gt;Now what’s going to happen if the productId supplied is less than zero? &lt;/p&gt;

&lt;p&gt;Well either the ProductRepository is going to throw an &lt;strong&gt;ArgumentOutOfRangeException &lt;/strong&gt;or it will return a null Product and the call to &lt;strong&gt;Product.ChangeName&lt;/strong&gt; is going to throw a &lt;strong&gt;NullReferenceException.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Either way an exception will be thrown after we have created a new Unit Of Work, which in practice could be an expensive operation.&amp;#160; &lt;span style="color: blue"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Take Two&lt;/h4&gt;

&lt;p&gt;So here is an example of how you could write the same method in a better way by first checking the arguments supplied satisfy the needs of the method. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;ChangeProductName(&lt;span style="color: blue"&gt;int &lt;/span&gt;productId, &lt;span style="color: blue"&gt;string &lt;/span&gt;name)
        {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(productId &amp;lt; 1)
            {
                &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentOutOfRangeException&lt;/span&gt;();
            }

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(name))
            {
                &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;();
            }

            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;uow = uowFactory.Create())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;product = productRepository.Get(productId);

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(product == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                {
                    &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProductNotFoundException&lt;/span&gt;(); 
                }

                product.ChangeName(name);

                uow.Commit();
            }

            &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;{ WasSuccessful = &lt;span style="color: blue"&gt;true &lt;/span&gt;}; 
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Take Three&lt;/h4&gt;

&lt;p&gt;Now the previous approach is bounds better than the first but we can reduce the lines of code by making use of some &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank"&gt;Extension Methods&lt;/a&gt; like so:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;ChangeProductName(&lt;span style="color: blue"&gt;int &lt;/span&gt;productId, &lt;span style="color: blue"&gt;string &lt;/span&gt;name)
        {
            productId.ValidateArgumentRange(1);
            name.ValidateArgumentNull(); 

            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;uow = uowFactory.Create())
            {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;product = productRepository.Get(productId);

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(product == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                {
                    &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProductNotFoundException&lt;/span&gt;(); 
                }

                product.ChangeName(name);

                uow.Commit();
            }

            &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OperationResult &lt;/span&gt;{ WasSuccessful = &lt;span style="color: blue"&gt;true &lt;/span&gt;}; 
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Extension Methods&lt;/h4&gt;

&lt;p&gt;Here are the extension methods that I use to take care of this. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentExtensions
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;public static void &lt;/span&gt;ValidateArgumentNull(&lt;span style="color: blue"&gt;this object &lt;/span&gt;value)
       {
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(value == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;();
           }
       }

       &lt;span style="color: blue"&gt;public static void &lt;/span&gt;ValidateArgumentRange(&lt;span style="color: blue"&gt;this int &lt;/span&gt;value, &lt;span style="color: blue"&gt;int &lt;/span&gt;min)
       {
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(value &amp;lt; min)
           {
               &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentOutOfRangeException&lt;/span&gt;();
           }
       }

       &lt;span style="color: blue"&gt;public static void &lt;/span&gt;ValidateArgumentRange(&lt;span style="color: blue"&gt;this int &lt;/span&gt;value, &lt;span style="color: blue"&gt;int &lt;/span&gt;min, &lt;span style="color: blue"&gt;int &lt;/span&gt;max)
       {
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(value &amp;lt; min || value &amp;gt; max)
           {
               &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentOutOfRangeException&lt;/span&gt;();
           }
       }
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;You maybe thinking to yourself that this is really simple stuff and I’d agree, but I felt it needed to be shared for those Devs who are still learning. &lt;/p&gt;

&lt;p&gt;There is a new project called &lt;a href="http://research.microsoft.com/en-us/projects/contracts/" target="_blank"&gt;Code Contracts&lt;/a&gt; which provides a way to explicitly define pre-conditions and post-conditions, this also allows to make use of Automatic testing tools such as &lt;a href="http://research.microsoft.com/en-us/projects/pex/" target="_blank"&gt;Pex&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;IMO a few years from now Code Contracts will be as fluent to a developer as Boolean operators and we will end up with better quality API’s because of it, however right now it is only a Research project so I’m hesitant to depend too highly on it until it’s finalised and becomes part of the core .NET Framework.&lt;/p&gt;

&lt;p&gt;There are also ways to approach this problem using Aspect-Oriented Programming but I will leave that to another post. &lt;/p&gt;

&lt;p&gt;Till next time.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/DZ_F4MXUrr0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/DZ_F4MXUrr0/defensive-programming-argument.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/defensive-programming-argument.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-3091513425920280474</guid><pubDate>Tue, 07 Sep 2010 13:00:00 +0000</pubDate><atom:updated>2010-09-07T21:00:00.932+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sys admin</category><category domain="http://www.blogger.com/atom/ns#">windows server</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">ec2</category><title>Load Balancing with Amazon EC2 and Elastic Load Balancing</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Hosting your applications in the cloud yields many benefits, however it can be at times a very scary place when thing’s go wrong, and they always do. &lt;/p&gt;  &lt;p&gt;If you love your customers then you owe it to them to make sure you have in place redundancy and ensure you provide a high level of availability. &lt;/p&gt;  &lt;p&gt;The &lt;a href="http://aws.amazon.com/ec2/" target="_blank"&gt;Amazon EC2&lt;/a&gt; Infrastructure provides a really easy way to set this up using the &lt;a href="http://aws.amazon.com/elasticloadbalancing/" target="_blank"&gt;Elastic Load Balancing&lt;/a&gt; feature.&lt;/p&gt;  &lt;p&gt;Before starting you need the basic concepts of how the EC2 infrastructure works and how it can help you in your quest for high availability. &lt;/p&gt;  &lt;h5&gt;Regions &lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;     &lt;br /&gt;&lt;/strong&gt;Regions in EC2 are geographical locations where the Data Centres reside and at the time of writing there are four Regions: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;US East – North Virginia &lt;/li&gt;    &lt;li&gt;US West – California &lt;/li&gt;    &lt;li&gt;EU – Ireland &lt;/li&gt;    &lt;li&gt;APAC – Singapore &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It goes without saying that the Region you select should be always be as close to your customers as possible.&lt;/p&gt;  &lt;h5&gt;Availability Zones&lt;/h5&gt;  &lt;p&gt;Each Region has 2 or more Availability Zones. These are important to understand as they are independent from each other in that a failure of one zone does not affect the other. &lt;/p&gt;  &lt;h3&gt;Network Diagram&lt;/h3&gt;  &lt;p&gt;This is a fairly typical approach to load balancing a web application but it’s important to note that the level of redundancy is achieved by putting different instances in different Availability Zones. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHp_b7_OjI/AAAAAAAAAXI/x7WRX7vh1Jo/s1600-h/LoadBalancingEC2%5B1%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="LoadBalancingEC2" border="0" alt="LoadBalancingEC2" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHp__WBB6I/AAAAAAAAAXM/GQYxTXBqUdE/LoadBalancingEC2_thumb%5B1%5D.jpg?imgmax=800" width="456" height="464" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The key thing to note here is that the instances you load balance should be in separate Availability Zones. &lt;/p&gt;  &lt;p&gt;This post will be covering the Load Balancing aspect as I will leave the database redundancy to another post. &lt;/p&gt;  &lt;h3&gt;Creating The Load Balancer&lt;/h3&gt;  &lt;p&gt;Creating the Load Balancer is easy using the &lt;a href="https://console.aws.amazon.com/" target="_blank"&gt;AWS Console&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Under Networking &amp;amp; Security &amp;gt; Load Balancers you can “Create Load Balancer”. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_la3Rv-0jOCI/TIHqA6jCv6I/AAAAAAAAAXQ/ltKy8MhnxUA/s1600-h/load_balancer%5B5%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer" border="0" alt="load_balancer" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TIHqBSGixTI/AAAAAAAAAXU/KESTyroxMpM/load_balancer_thumb%5B3%5D.jpg?imgmax=800" width="717" height="539" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This should be fairly self explanatory.&lt;/p&gt;  &lt;p&gt;First we are assigning a name to our Load Balancer and then we are setting up the Ports the Load Balancer should listen on and forward to. &lt;/p&gt;  &lt;p&gt;If you want to use HTTPS then you will need to do Port Forwarding as show in the highlighted image.&lt;/p&gt;  &lt;h5&gt;Configure Health Check&lt;/h5&gt;  &lt;p&gt;Next you need to setup your Health Check, this is how the Load Balancer decides if your Instance can have requests forwarded to it. &lt;/p&gt;  &lt;p&gt;You can do this by setting the Ping Path which is an HTTP resource that is polled at an interval you define. &lt;/p&gt;  &lt;p&gt;If it returns an HTTP result code other than 200 it will cause your instance to be deemed unhealthy and subsequently removed from the Load Balancer. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TIHqCZ2NnRI/AAAAAAAAAXY/asOeJxQJ5xc/s1600-h/load_balancer_check%5B15%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer_check" border="0" alt="load_balancer_check" src="http://lh4.ggpht.com/_la3Rv-0jOCI/TIHqDN3W5_I/AAAAAAAAAXc/AeGTAgDlGWo/load_balancer_check_thumb%5B13%5D.jpg?imgmax=800" width="717" height="563" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The Ping Path can be a static HTML resource, however it’s a good idea to run other any system checks and so I like to use a .ASPX file with Code-Behind instead. &lt;/p&gt;  &lt;h5&gt;Adding Instances&lt;/h5&gt;  &lt;p&gt;Here you can select Instances from all Availability Zones in your Region, as I mentioned before you should select Instances in different Availability Zones to provide a higher level of availability. Although you can have a single instance, it goes without saying you should have at least two. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TIHqD-nfq5I/AAAAAAAAAXg/o7GVT9DBMr8/s1600-h/load_balancer_add_instances%5B14%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer_add_instances" border="0" alt="load_balancer_add_instances" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHqEnm2t4I/AAAAAAAAAXk/lY3DOQxMLZ8/load_balancer_add_instances_thumb%5B12%5D.jpg?imgmax=800" width="717" height="556" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;DNS&lt;/h5&gt;  &lt;p&gt;When a load balancer is created it automatically gets assigned a DNS Name. To point your website address to your load balancer all you have to do is create a CNAME record for it. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TIHqFFyiOBI/AAAAAAAAAXo/kbTQKQ3gndw/s1600-h/load_balancer_dns%5B7%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer_dns" border="0" alt="load_balancer_dns" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TIHqFhKF9XI/AAAAAAAAAXs/PaIPi_ai--U/load_balancer_dns_thumb%5B5%5D.jpg?imgmax=800" width="730" height="132" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Managing The Load Balancer&lt;/h3&gt;  &lt;p&gt;Now that you have setup your load balancer you can add more instances easily and get visibility of the Health of each instances by selecting the Load Balancer in the AWS Console. &lt;/p&gt;  &lt;h5&gt;Healthy&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_la3Rv-0jOCI/TIHqGZi4POI/AAAAAAAAAXw/q2RZPTeqRGw/s1600-h/load_balancer_healthy%5B8%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer_healthy" border="0" alt="load_balancer_healthy" src="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHqGzVxW0I/AAAAAAAAAX0/ENTZoBGwth0/load_balancer_healthy_thumb%5B6%5D.jpg?imgmax=800" width="722" height="386" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Unhealthy&lt;/h5&gt;  &lt;p&gt;And this is what it looks like if you have an unhealthy instance. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHqHpVKaqI/AAAAAAAAAX4/hPFxxnQDeI4/s1600-h/load_balancer_unhealthy%5B8%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancer_unhealthy" border="0" alt="load_balancer_unhealthy" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TIHqIROWwHI/AAAAAAAAAX8/0PBYk4GusUs/load_balancer_unhealthy_thumb%5B4%5D.jpg?imgmax=800" width="721" height="339" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Key Issues&lt;/h3&gt;  &lt;p&gt;Although EC2 alleviates lot of pain out of setting up a load balanced solution there are a few issues you need to be aware of before diving headfirst into this solution. &lt;/p&gt;  &lt;h5&gt;Connection Timeout Limit&lt;/h5&gt;  &lt;p&gt;At present the load balancer does not hold connections open for more than 60 seconds by design. So if you have any requests which take longer than a minute you are going run into problems. If you do find yourself in this position you should really be looking at how to reduce the Response times by using one-way Messaging or reducing the operation. &lt;/p&gt;  &lt;h5&gt;Static IP Address Support&lt;/h5&gt;  &lt;p&gt;Unfortunately there is currently no support for a Static IP address for your load balancer. So if you are integrating with third parties who have strict firewall policies then you may have problems. I’m hoping though that Amazon add this feature in the future as it is needed in a lot of scenarios.&lt;/p&gt;  &lt;h5&gt;SSL Support &lt;/h5&gt;  &lt;p&gt;To enable HTTPS you have to use port forwarding at the load balancer level, which can be achieved by listening on &lt;strong&gt;443&lt;/strong&gt; and then forwarding to another port for instance &lt;strong&gt;8443&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;In IIS you then need to change the port in the Site Bindings, and don’t forget to open &lt;strong&gt;8443&lt;/strong&gt; on your Firewall.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_la3Rv-0jOCI/TIHqJHLSofI/AAAAAAAAAYA/zweAGMVJarc/s1600-h/load_balancing_iss_bindings%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="load_balancing_iss_bindings" border="0" alt="load_balancing_iss_bindings" src="http://lh5.ggpht.com/_la3Rv-0jOCI/TIHqJoA1leI/AAAAAAAAAYE/Aavpts8g4oU/load_balancing_iss_bindings_thumb%5B1%5D.jpg?imgmax=800" width="381" height="217" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Sticky Sessions &lt;/h5&gt;  &lt;p&gt;The Elastic Load Balancer does support Sticky Sessions via Cookies or QueryString however it is only works for Port 80 traffic.&amp;#160;&amp;#160; &lt;br /&gt;So if you’re using InProcess Session State you will need to move to the SQL based provider. &lt;/p&gt;  &lt;h5&gt;&lt;strong&gt;Cache&lt;/strong&gt;&amp;#160; &lt;/h5&gt;  &lt;p&gt;If you’re using &lt;strong&gt;System.Web.Caching.Cache&lt;/strong&gt; to cache objects then you’re also going to run into issues because of the Sticky Session problem on HTTPS. If Caching is a critical factor in your applications performance then you will need to consider a Distributed Cache solution like &lt;a href="http://memcached.org/" target="_blank"&gt;Memcache&lt;/a&gt; or &lt;a href="http://www.sharedcache.com/cms/" target="_blank"&gt;Shared Cache&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Well that’s about all there is to it. I hope this helps someone. &lt;/p&gt;  &lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/4qnhtBAUMxU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/4qnhtBAUMxU/load-balancing-with-amazon-ec2-and.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_la3Rv-0jOCI/TIHp__WBB6I/AAAAAAAAAXM/GQYxTXBqUdE/s72-c/LoadBalancingEC2_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/load-balancing-with-amazon-ec2-and.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-2255116399353687544</guid><pubDate>Thu, 02 Sep 2010 13:00:00 +0000</pubDate><atom:updated>2010-09-02T21:00:03.231+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">aop</category><category domain="http://www.blogger.com/atom/ns#">castle windsor</category><title>Implementing Custom Castle Windsor Facilities</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you’ve been following my posts you would know that I love &lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Castle Windsor&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;One of the many useful features I have found is the &lt;a href="http://www.castleproject.org/container/facilities/v1rc3/index.html" target="_blank"&gt;Facility&lt;/a&gt; and I’m going to try and give a good example how you can make use of this. &lt;/p&gt;  &lt;p&gt;In a &lt;a href="http://blog.willbeattie.net/2010/08/caching-as-cross-cutting-concern-using.html" target="_blank"&gt;recent post&lt;/a&gt; I showed how you can add Cross-Cutting concerns to your application by using Interceptors.&lt;/p&gt;  &lt;p&gt;Now when configuring the Container you can explicitly configure each Interceptor per Service but when you have lot’s of components it can get pretty hard to maintain after a while and can also introduce subtle issues if someone forgets to configure it correctly.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Below is how you would configure your Container &lt;strong&gt;without &lt;/strong&gt;using a Facility. On the last line we are specifying the Interceptor explicitly. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;Configure()
        {
            container = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer&lt;/span&gt;();

            container.Register(
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;&amp;gt;(),
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICacheProvider&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;WebCacheProvider&lt;/span&gt;&amp;gt;().LifeStyle.Singleton,
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;CatalogQueryService&lt;/span&gt;&amp;gt;()
                    .LifeStyle.Transient
&lt;strong&gt;                    .Interceptors(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InterceptorReference&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;))).Anywhere);&lt;/strong&gt;
        }&lt;/pre&gt;

&lt;p&gt;Or the XML version &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;castle&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;components&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;CacheInterceptor&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Aop.CacheInterceptor, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Aop.CacheInterceptor, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ICatalogQueryService&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Services.ICatalogQueryService, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Services.Impl.CatalogQueryService, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;interceptors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;interceptor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;${CacheInterceptor}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;interceptor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;interceptors&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ICacheProvider&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Core.Cache.ICacheProvider, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Core.Cache.Impl.WebCacheProvider, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;components&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;castle&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What would be nice would be to be able to specify the Interceptor on all Components automagically and Castle allows for this with Facilities. Below is an implementation which achieves the desired result. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CacheInterceptionFacility &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;AbstractFacility
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;protected override void &lt;/span&gt;Init()
       {
           Kernel.ComponentRegistered += Kernel_ComponentRegistered;
       }

       &lt;span style="color: blue"&gt;private void &lt;/span&gt;Kernel_ComponentRegistered(&lt;span style="color: blue"&gt;string &lt;/span&gt;key, &lt;span style="color: #2b91af"&gt;IHandler &lt;/span&gt;handler)
       {
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;IMustBeCached&lt;/span&gt;).IsAssignableFrom(handler.ComponentModel.Implementation))
           {
               handler.ComponentModel.Interceptors
                   .Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InterceptorReference&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;)));
           }
       }
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;All you have to do is Inherit from the Castle.MicroKernel.Facilities.AbstractFacility and then override the Init. &lt;/p&gt;

&lt;p&gt;You’ll see that we use the Interface IMustBeCached to identify the Component to apply the Interceptor too. &lt;/p&gt;

&lt;p&gt;Now in your Bootstrapper all you have to do is call AddFacility on the WindsorContainer and you’re good to go. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;Configure()
        {
            container = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer&lt;/span&gt;();

            container.Register(
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;&amp;gt;(),
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICacheProvider&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;WebCacheProvider&lt;/span&gt;&amp;gt;().LifeStyle.Singleton,
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;CatalogQueryService&lt;/span&gt;&amp;gt;().LifeStyle.Transient);

            container.AddFacility(&lt;span style="color: #a31515"&gt;&amp;quot;CacheInterceptionFacility&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CacheInterceptionFacility&lt;/span&gt;()); 

        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Or the XML version &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;castle&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;facilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;facility
      &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;CacheInterceptionFacility&lt;/span&gt;&amp;quot;
      &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Aop.CacheInterceptionFacility, MyApp&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;facility&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;facilities&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;components&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;CacheInterceptor&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Aop.CacheInterceptor, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Aop.CacheInterceptor, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ICatalogQueryService&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Services.ICatalogQueryService, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Services.Impl.CatalogQueryService, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;component &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;ICacheProvider&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;service&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Core.Cache.ICacheProvider, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyApp.Core.Cache.Impl.WebCacheProvider, MyApp&lt;/span&gt;&amp;quot;
             &lt;span style="color: red"&gt;lifestyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
  &lt;/span&gt;&lt;span style="color: blue"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;component&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;components&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;castle&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Aside from reducing the configuration overhead another benefit of using this approach is that in your Debug or Test Environments you can easily deploy without any Interceptors and only enable them in your Staging and Production environments. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&amp;#160;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/rKIPHacdWgQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/rKIPHacdWgQ/implementing-custom-castle-windsor.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/implementing-custom-castle-windsor.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-136097127055528265</guid><pubDate>Tue, 31 Aug 2010 13:00:00 +0000</pubDate><atom:updated>2010-08-31T21:00:08.493+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ioc</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">aop</category><category domain="http://www.blogger.com/atom/ns#">castle windsor</category><title>Caching as Cross-Cutting Concern Part 2 – Invalidating the Cache</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In my &lt;a href="http://blog.willbeattie.net/2010/08/caching-as-cross-cutting-concern-using.html" target="_blank"&gt;previous post&lt;/a&gt; I showed how you can very easily add Caching to your application by using Castle Windsor.&lt;/p&gt;  &lt;p&gt;The example used was a very basic implementation and whilst it can be useful for a large number of cases it didn’t cover the all important cache invalidation. &lt;/p&gt;  &lt;p&gt;In this post I hope to explain how with a bit of convention over configuration how you can invalidate your cache when an object changes.&lt;/p&gt;  &lt;p&gt;In the last post I was using the Method name combined with the arguments to build the cache key. Now to allow us to build a cache key that can be used when invalidating the cache the key needs to be related to the Result type.&lt;/p&gt;  &lt;p&gt;For this I’m going to create a simple interface called IAmCacheable to identify the object we want to cache.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IAmCacheable
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;object &lt;/span&gt;Key { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }
    }&lt;/pre&gt;

&lt;p&gt;And make sure the object we want to cache implements this interface. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IAmCacheable 
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public object &lt;/span&gt;Key { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }

        &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now we have to change the CacheInterceptor&amp;#160; to build the Cache Key based on the combination of the Type and the Id. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CacheInterceptor &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IInterceptor
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider;

       &lt;span style="color: blue"&gt;private const int &lt;/span&gt;CacheExpiryMinutes = 1; 

       &lt;span style="color: blue"&gt;public &lt;/span&gt;CacheInterceptor(&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider)
       {
           &lt;span style="color: blue"&gt;this&lt;/span&gt;.cacheProvider = cacheProvider; 
       }

       &lt;span style="color: blue"&gt;#region &lt;/span&gt;IInterceptor Members

       &lt;span style="color: blue"&gt;public void &lt;/span&gt;Intercept(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
       {
           &lt;span style="color: green"&gt;//check if the method has a return value
           &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(invocation.Method.ReturnType == &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;void&lt;/span&gt;))
           {
               invocation.Proceed();
               &lt;span style="color: blue"&gt;return&lt;/span&gt;; 
           }

           &lt;span style="color: green"&gt;//check to see if the return type implements IAmCacheable
           &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;returnTypeIsCacheable = &lt;span style="color: blue"&gt;typeof &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;IAmCacheable&lt;/span&gt;)
               .IsAssignableFrom(invocation.Method.ReturnType); 

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(!returnTypeIsCacheable)
           {
               invocation.Proceed();
               &lt;span style="color: blue"&gt;return&lt;/span&gt;;
           }

           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = BuildCacheKeyFrom(invocation); 
          
           &lt;span style="color: green"&gt;//try get the return value from the cache provider
           &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;item = cacheProvider.Get(cacheKey); 

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               invocation.ReturnValue = item;
               &lt;span style="color: blue"&gt;return&lt;/span&gt;;
           }

           &lt;span style="color: green"&gt;//call the interecepted method
           &lt;/span&gt;invocation.Proceed();

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(invocation.ReturnValue != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               cacheProvider.Put(cacheKey, CacheExpiryMinutes, invocation.ReturnValue); 
           }

           &lt;span style="color: blue"&gt;return&lt;/span&gt;;
       }

       &lt;span style="color: blue"&gt;#endregion

       private static string &lt;/span&gt;BuildCacheKeyFrom(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
       {
           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheableTypeName = invocation.Method.ReturnType.Name;
           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = &lt;span style="color: #a31515"&gt;&amp;quot;{0}-{1}&amp;quot;&lt;/span&gt;;

           &lt;span style="color: blue"&gt;var &lt;/span&gt;keyArgName = &lt;span style="color: #a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;;

           &lt;span style="color: blue"&gt;var &lt;/span&gt;prms = invocation.Method.GetParameters();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;keyIndex = prms.TakeWhile(prm =&amp;gt; prm.Name != keyArgName).Count();

           &lt;span style="color: blue"&gt;var &lt;/span&gt;keyValue = invocation.Arguments[keyIndex]; 

           &lt;span style="color: blue"&gt;return string&lt;/span&gt;.Format(cacheKey, cacheableTypeName, keyValue); 

       }

   }&lt;/pre&gt;

&lt;p&gt;The main change here is in the BuildCacheKeyFrom method. What I’m doing here is looking for the value of the Argument named “id” and using this combined with the Type name to build the key which would end up like “Product-1”.&lt;/p&gt;

&lt;p&gt;Now that we’ve changed the logic to build the Cache Key we need to be remove the object from the Cache when it changes. &lt;/p&gt;

&lt;p&gt;Similar to the IMustBeCached interface in the first article we create an interface called IInvalidateCache to identity which call to apply the invalidation interceptor on. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IInvalidateCache
   &lt;/span&gt;{
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;And we’ll make the IProductRepository implement this like so. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IProductRepository &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IInvalidateCache
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;Get(&lt;span style="color: blue"&gt;int &lt;/span&gt;id);

        &lt;span style="color: blue"&gt;void &lt;/span&gt;Update(&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;product);
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now we need a new type of Interceptor called CacheInvalidationInterceptor which removes any IAmCacheable objects from the cache when they are passed as arguments to any method.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CacheInvalidationInterceptor &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IInterceptor
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;CacheInvalidationInterceptor(&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider)
        {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.cacheProvider = cacheProvider;
        }

        &lt;span style="color: blue"&gt;#region &lt;/span&gt;IInterceptor Members

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Intercept(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
        {
            &lt;span style="color: green"&gt;//check to see if any argument implements IAmCacheable
            &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;hasCacheableArgument = invocation.Arguments.Any(a =&amp;gt; a &lt;span style="color: blue"&gt;is &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IAmCacheable&lt;/span&gt;);

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!hasCacheableArgument)
            {
                invocation.Proceed();
                &lt;span style="color: blue"&gt;return&lt;/span&gt;;
            }

            &lt;span style="color: green"&gt;//call the intercepted method
            &lt;/span&gt;invocation.Proceed();

            &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = BuildCacheKeyFrom(invocation);

            &lt;span style="color: green"&gt;//remove the item from the cache
            &lt;/span&gt;cacheProvider.Remove(cacheKey); 

            &lt;span style="color: blue"&gt;return&lt;/span&gt;;
        }

        &lt;span style="color: blue"&gt;#endregion

        private static string &lt;/span&gt;BuildCacheKeyFrom(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheable = invocation.Arguments.First(a =&amp;gt; a &lt;span style="color: blue"&gt;is &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IAmCacheable&lt;/span&gt;) &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IAmCacheable&lt;/span&gt;; 

            &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheableTypeName = cacheable.GetType().Name;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = &lt;span style="color: #a31515"&gt;&amp;quot;{0}-{1}&amp;quot;&lt;/span&gt;;

            &lt;span style="color: blue"&gt;return string&lt;/span&gt;.Format(cacheKey, cacheableTypeName, cacheable.Key);

        }

    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;All we do here is look for any Arguments which implement IAmCacheable and then use a combination of the Type name and the IAmCacheable.Key to build the cache key. &lt;/p&gt;

&lt;p&gt;We also make sure the method is called first by calling Invocation.Proceed before removing the item from the Cache. &lt;/p&gt;

&lt;p&gt;Finally we need to wire up this new Interceptor in the Bootstrapper. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;        public void &lt;/span&gt;Configure()
        {
            container = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer&lt;/span&gt;();

            container.Register(
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;&amp;gt;(),
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICacheProvider&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;WebCacheProvider&lt;/span&gt;&amp;gt;().LifeStyle.Singleton,
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;CatalogQueryService&lt;/span&gt;&amp;gt;()
                    .LifeStyle.Transient
                    .Interceptors(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InterceptorReference&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;))).Anywhere);


            container.Register(
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;CacheInvalidationInterceptor&lt;/span&gt;&amp;gt;(),
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;IProductRepository&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;ProductRepository&lt;/span&gt;&amp;gt;()
                    .LifeStyle.Transient
                    .Interceptors(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InterceptorReference&lt;/span&gt;(
                        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CacheInvalidationInterceptor&lt;/span&gt;)))
                        .Anywhere);


        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This is my final post on the subject. Hope this gives you some ideas on how to implement Caching or other Cross-Cutting concerns using AOP. &lt;/p&gt;

&lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/IQfiXjyemao" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/IQfiXjyemao/caching-as-cross-cutting-concern-part-2.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/09/caching-as-cross-cutting-concern-part-2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-8646984376516275486</guid><pubDate>Tue, 24 Aug 2010 13:00:00 +0000</pubDate><atom:updated>2010-08-24T21:00:10.516+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">ioc</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">aop</category><title>Caching as a Cross-Cutting Concern using Castle Windsor</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This post assumes knowledge of Dependency Injection and AOP. &lt;/p&gt;  &lt;p&gt;AOP or &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" target="_blank"&gt;Aspect-Oriented Programming&lt;/a&gt; is a very powerful way to add &lt;a href="http://en.wikipedia.org/wiki/Cross-cutting_concern" target="_blank"&gt;Cross-Cutting concerns&lt;/a&gt; to a system without impacting the core code base. Cross-Cutting concerns can cover non-functional requirements and also functional requirements.&lt;/p&gt;  &lt;p&gt;There are generally three approaches when implementing AOP. &lt;/p&gt;  &lt;p&gt;1. Generate Dynamic Proxies at runtime to intercept method calls&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.springframework.net/" target="_blank"&gt;Spring .NET&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Castle Windsor&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;2. Post-Compilation Assembly Transformation&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.sharpcrafters.com/postsharp" target="_blank"&gt;Post Sharp&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;3. &lt;a href="http://msdn.microsoft.com/en-us/library/system.attribute.aspx" target="_blank"&gt;Attributes&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Just using Plain Old Attributes &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I really really don’t like annotating classes &amp;amp; members with Attributes so for me Dynamic Proxies is the only option and the performance hit is worth the productivity gains. &lt;/p&gt;  &lt;p&gt;The very common example of AOP is Logging. Logging is by all accounts a Cross-Cutting concern and so lends itself very well to the example.&lt;/p&gt;  &lt;p&gt;However I tend to think of Caching as a Cross-Cutting concern and really hate to see code like the below.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;       public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;GetProductById(&lt;span style="color: blue"&gt;int &lt;/span&gt;id)
       {
           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;Product-&amp;quot;&lt;/span&gt;, id);

           &lt;span style="color: blue"&gt;var &lt;/span&gt;cache = &lt;span style="color: #2b91af"&gt;HttpRuntime&lt;/span&gt;.Cache;

           &lt;span style="color: blue"&gt;var &lt;/span&gt;product = cache.Get(cacheKey) &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;; 

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(product != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               &lt;span style="color: blue"&gt;return &lt;/span&gt;product; 
           }

           product = productRepository.Get(id);

           cache.Add(cacheKey, product, &lt;span style="color: blue"&gt;null&lt;/span&gt;, 
               System.Web.Caching.&lt;span style="color: #2b91af"&gt;Cache&lt;/span&gt;.NoAbsoluteExpiration, 
               System.Web.Caching.&lt;span style="color: #2b91af"&gt;Cache&lt;/span&gt;.NoSlidingExpiration, &lt;span style="color: #2b91af"&gt;CacheItemPriority&lt;/span&gt;.High, &lt;span style="color: blue"&gt;null&lt;/span&gt;);

           &lt;span style="color: blue"&gt;return &lt;/span&gt;product; 

       }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;IMO the above code block only adds noise to your code base and makes it harder to read. It’s also prone to logic errors if it’s being implemented in many places and so is a prime candidate for AOP. &lt;/p&gt;

&lt;p&gt;In this example I will be using &lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Castle Windsor&lt;/a&gt; just because I am most familiar with it, but any good Dependency Injection framework should support AOP.&amp;#160; &lt;/p&gt;

&lt;p&gt;In Castle Windsor there is a concept of an Interceptor which as the name implies intercepts any method calls on a class. Behind the scenes this is implemented using &lt;a href="http://www.castleproject.org/dynamicproxy/index.html" target="_blank"&gt;DyanmicProxy&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Let’s first have a look at a fairly contrived example of a Service that we want to add Caching too. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;GetProductById(&lt;span style="color: blue"&gt;int &lt;/span&gt;id); 
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;
  &lt;br /&gt;Now in order to configure the Service to use our Interceptor we need a way to identify which class we want to apply the interceptor too. You can use Attributes or explicitly set the interceptor when configuring the Container however I prefer is to use an Interface to explicitly mark which Interface should be intercepted. This allows you to easily configure a &lt;a href="http://www.castleproject.org/container/documentation/v21/concepts/facility.html" target="_blank"&gt;Facility&lt;/a&gt; but that’s a topic for another post. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IMustBeCached
    &lt;/span&gt;{
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;So after that I change the ICatalogQueryService to implement the IMustBeCached interface. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;    public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IMustBeCached 
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Product &lt;/span&gt;GetProductById(&lt;span style="color: blue"&gt;int &lt;/span&gt;id); 
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The next and most important part is creating the Interceptor, this has to implement the Castle.Core.Interceptor.IInterceptor interface. &lt;/p&gt;

&lt;p&gt;So here it is, in&amp;#160; just a few lines of code we have implemented a reusable Cache policy that caches all return values for one minute and our ICatalogQueryService implementation is none the wiser. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;   public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CacheInterceptor &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IInterceptor
   &lt;/span&gt;{
       &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider;

       &lt;span style="color: blue"&gt;private const int &lt;/span&gt;CacheExpiryMinutes = 1; 

       &lt;span style="color: blue"&gt;public &lt;/span&gt;CacheInterceptor(&lt;span style="color: #2b91af"&gt;ICacheProvider &lt;/span&gt;cacheProvider)
       {
           &lt;span style="color: blue"&gt;this&lt;/span&gt;.cacheProvider = cacheProvider; 
       }

       &lt;span style="color: blue"&gt;#region &lt;/span&gt;IInterceptor Members

       &lt;span style="color: blue"&gt;public void &lt;/span&gt;Intercept(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
       {
           &lt;span style="color: green"&gt;//check if the method has a return value
           &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(invocation.Method.ReturnType == &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Void&lt;/span&gt;))
           {
               invocation.Proceed();
               &lt;span style="color: blue"&gt;return&lt;/span&gt;; 
           }

           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = BuildCacheKeyFrom(invocation); 
          
           &lt;span style="color: green"&gt;//try get the return value from the cache provider
           &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;item = cacheProvider.Get(cacheKey); 

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               invocation.ReturnValue = item;
               &lt;span style="color: blue"&gt;return&lt;/span&gt;;
           }

           &lt;span style="color: green"&gt;//call the intercepted method
           &lt;/span&gt;invocation.Proceed();

           &lt;span style="color: blue"&gt;if &lt;/span&gt;(invocation.ReturnValue != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               cacheProvider.Put(cacheKey, CacheExpiryMinutes, invocation.ReturnValue); 
           }

           &lt;span style="color: blue"&gt;return&lt;/span&gt;;
       }

       &lt;span style="color: blue"&gt;#endregion

       private static string &lt;/span&gt;BuildCacheKeyFrom(&lt;span style="color: #2b91af"&gt;IInvocation &lt;/span&gt;invocation)
       {
           &lt;span style="color: blue"&gt;var &lt;/span&gt;methodName = invocation.Method.Name;

           &lt;span style="color: blue"&gt;var &lt;/span&gt;arguments = (&lt;span style="color: blue"&gt;from &lt;/span&gt;a &lt;span style="color: blue"&gt;in &lt;/span&gt;invocation.Arguments &lt;span style="color: blue"&gt;select &lt;/span&gt;a.ToString()).ToArray();
           &lt;span style="color: blue"&gt;var &lt;/span&gt;argsString = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #a31515"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, arguments);

           &lt;span style="color: blue"&gt;var &lt;/span&gt;cacheKey = methodName + &lt;span style="color: #a31515"&gt;&amp;quot;-&amp;quot; &lt;/span&gt;+ argsString;

           &lt;span style="color: blue"&gt;return &lt;/span&gt;cacheKey; 

       }
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now all that’s left to do is tie it to configure the Windsor Container to use the Interceptor. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;     public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Bootstrapper
     &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer &lt;/span&gt;container; 
        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer &lt;/span&gt;Container
        {
            &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;container;  }
        }

        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Configure()
        {
            container = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WindsorContainer&lt;/span&gt;();

            container.Register(
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;&amp;gt;(),
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICacheProvider&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;WebCacheProvider&lt;/span&gt;&amp;gt;().LifeStyle.Singleton,
                &lt;span style="color: #2b91af"&gt;Component&lt;/span&gt;.For&amp;lt;&lt;span style="color: #2b91af"&gt;ICatalogQueryService&lt;/span&gt;&amp;gt;()
                    .ImplementedBy&amp;lt;&lt;span style="color: #2b91af"&gt;CatalogQueryService&lt;/span&gt;&amp;gt;()
                    .LifeStyle.Transient
                    .Interceptors(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InterceptorReference&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CacheInterceptor&lt;/span&gt;))).Anywhere);

        }
     }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The other great thing about this is that you can turn caching on or off just by configuring the Container.&amp;#160; &lt;br /&gt;Usually I will only enable Interceptors when in the Staging &amp;amp; Production environments and so keep any Cache out of the Debug environment as it can be problematic. &lt;/p&gt;

&lt;p&gt;That’s all there is to it. Feel free to comment if you have any questions. &lt;/p&gt;

&lt;p&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/0kNFK9ldGp8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/0kNFK9ldGp8/caching-as-cross-cutting-concern-using.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>5</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/08/caching-as-cross-cutting-concern-using.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-3448941519750774754</guid><pubDate>Sun, 15 Aug 2010 22:00:00 +0000</pubDate><atom:updated>2010-08-16T09:12:52.332+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">recruitment</category><category domain="http://www.blogger.com/atom/ns#">offtopic</category><title>Top 10 Job Interview Tips for Software Developers</title><description>&lt;p&gt;This post maybe a little off the usual thread of my usual Technical posts but I feel it has to be said. &lt;/p&gt;  &lt;p&gt;Since moving to Singapore and trying to build a development team I have found myself inundated with resumes, in the last 6 months alone I have probably read in excess of 500 resumes and interviewed less than 5% of that number and thought I would share some tips for any hopeful developers. &lt;/p&gt;  &lt;p&gt;Most of this should be common sense, but the funny thing about common sense is that it’s not so common. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. Prepare      &lt;br /&gt;&lt;/strong&gt;Research the company before going for an interview. If you know who’s interviewing you then &lt;a href="http://www.google.com/#hl=en&amp;amp;source=hp&amp;amp;q=will+beattie&amp;amp;aq=f&amp;amp;aqi=g-p3&amp;amp;aql=&amp;amp;oq=&amp;amp;gs_rfai=&amp;amp;fp=1" target="_blank"&gt;Google&lt;/a&gt; them and see what they’re about. This can help give you an idea of the types of questions you will get in the interview. &lt;/p&gt;  &lt;p&gt;There’s no excuse for not even having a basic idea of what the companies core business is. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. Acronyms != Interesting Resume &lt;/strong&gt;    &lt;br /&gt;There are no prizes for the most acronyms you list. As a rule only list those that you are able to discuss in detail for two minutes or more. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Relevance      &lt;br /&gt;&lt;/strong&gt;Customize your resume for the specific role you are applying for.     &lt;br /&gt;    &lt;br /&gt;If it’s a C# role, then a full page dedicated to a project you did using COBOL back in the 80’s is not going to win you any points. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. Keep It Simple Stupid (KISS)&lt;/strong&gt;     &lt;br /&gt;Keep your resume to four pages or less. Write it so that all the important information can be viewed in 10 seconds or less.     &lt;br /&gt;Bullet points are as always a great way of conveying concise information. &lt;/p&gt;  &lt;p&gt;I usually read resumes on my iPhone whilst on the daily commute so less is best. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;5. Be Honest      &lt;br /&gt;&lt;/strong&gt;Don’t exaggerate your years of experience. The fact you did a one month internship in your final year of study does not equate to one years work experience. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;6. Read the Ad      &lt;br /&gt;&lt;/strong&gt;Read the job ad carefully and follow any instructions. If the ad says “Please apply via our Job Portal” then actually apply via their job portal and not via the website the ad is on.&amp;#160; &lt;br /&gt;    &lt;br /&gt;Attention to detail and the ability to follow instructions are paramount to the success of a developer. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;7. Not too Early, Not too Late      &lt;br /&gt;&lt;/strong&gt;There is a fine line between arriving too early and arriving too late, for me that line is 15 minutes either side of the interview time. &lt;/p&gt;  &lt;p&gt;Even though it is annoying I am less concerned with candidates who arrive more than 15 minutes early. But if you’re more than 15 minutes late and don’t call then to let me know you’ll be late then you shouldn’t bother coming in at all. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;8. Communication      &lt;br /&gt;&lt;/strong&gt;Communication is key to the success of any development team &amp;amp; it’s important to demonstrate this in the interview.&amp;#160;&amp;#160; &lt;br /&gt;Listen to the questions and take the time to formulate answers before speaking, avoid mono-syllabic answers but also be careful not to hijack the interview. An interview is not the time for you to rant incessantly about the latest “X” technology. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;9. Ask Questions      &lt;br /&gt;&lt;/strong&gt;Asking questions shows that you are inquisitive mind and able to communicate effectively, again both skills that are important for an aspiring Developer. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;10. Keep your Web Presence Clean      &lt;br /&gt;&lt;/strong&gt;The first thing I do and many recruiters do is type the name of a candidate into Google and see what results it brings up.&lt;/p&gt;  &lt;p&gt;No presence at all can show that you’re not engaged with the community. On the flipside those photos of you wasted at the weekend do nothing to help your cause.    &lt;br /&gt;    &lt;br /&gt;My usual process is to search Google, Facebook, Twitter and LinkedIn. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Well that’s my list. &lt;/p&gt;  &lt;p&gt;If you’re a C# Developer or JavaScript whizz and fancy working in Singapore then check out some of our &lt;a href="http://jobsearch.monster.com.sg/searchresult.html?fts=ebus" target="_blank"&gt;job openings&lt;/a&gt; or drop me a line on &lt;a href="mailto:will@willbeattie.net"&gt;will@willbeattie.net&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/BnXffvwxfww" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/BnXffvwxfww/top-10-job-interview-tips-for-software.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/08/top-10-job-interview-tips-for-software.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-4773068903331329383</guid><pubDate>Thu, 29 Jul 2010 04:49:00 +0000</pubDate><atom:updated>2010-08-02T20:39:41.539+08:00</atom:updated><title>Cannot load reference assembly Error 13 .NET 4.0 SvcUtil</title><description>&lt;p&gt;Just ran into this nice error while trying to generate a proxy using the &lt;a href="http://msdn.microsoft.com/en-us/library/aa347733.aspx" target="_blank"&gt;SvcUtil&lt;/a&gt; and /reference option in a .NET 4.0 Project. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Error&amp;#160;&amp;#160;&amp;#160; 13&amp;#160;&amp;#160;&amp;#160; Cannot load reference assembly 'C:\MySource\bin\Debug\MyReference.dll'&lt;/em&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;The solution makes total sense as the current version of SvcUtil is for .NET 3.5 only. &lt;/p&gt;  &lt;p&gt;You can get around this by changing your path to: &lt;/p&gt;  &lt;p&gt;C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\&lt;strong&gt;NETFX 4.0 Tools\&lt;/strong&gt;svcutil.exe&lt;/p&gt;  &lt;p&gt;Alternatively you can &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=6B6C21D2-2006-4AFA-9702-529FA782D63B&amp;amp;displaylang=en" target="_blank"&gt;download the latest Microsoft Windows SDK for Windows 7 and .NET Framework 4&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And then change the SvcUtil path to: &lt;/p&gt;  &lt;p&gt;C:\Program Files\Microsoft SDKs\Windows\&lt;strong&gt;v7.1&lt;/strong&gt;\bin\NETFX 4.0 Tools\svcutil.exe&lt;/p&gt;  &lt;p&gt;Hope this helps someone. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/LjOOWwTgJG8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/LjOOWwTgJG8/cannot-load-reference-assembly-error-13.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/07/cannot-load-reference-assembly-error-13.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-3042870283841296946</guid><pubDate>Tue, 20 Jul 2010 03:26:00 +0000</pubDate><atom:updated>2010-07-20T11:26:49.475+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">flex</category><category domain="http://www.blogger.com/atom/ns#">bug</category><category domain="http://www.blogger.com/atom/ns#">flash</category><title>Flex Builder 3 changes not reflected in compiled SWF</title><description>&lt;p&gt;I have just spent the last 2 hours trying to figure out why my none of my changes were reflected in the compiled SWF.&lt;/p&gt;  &lt;p&gt;Thankfully I came across this &lt;a href="http://www.rubenswieringa.com/blog/flex-3-stop-running-the-old-version-of-my-swf" target="_blank"&gt;post&lt;/a&gt; where one of the comments had the solution. &lt;/p&gt;  &lt;p&gt;If you have a SWF named &amp;lt;PROJECTNAME&amp;gt;.swf in the &lt;strong&gt;html-template&lt;/strong&gt; then deleting it will fix this issue. &lt;/p&gt;  &lt;p&gt;Apparently the existence of this file means that when you do a Build or Release Export it just copies this file and does &lt;strong&gt;NOT &lt;/strong&gt;compile the latest source code. &lt;/p&gt;  &lt;p&gt;Makes sense to me!&lt;/p&gt;  &lt;p&gt;It turns out that it’s a &lt;a href="http://bugs.adobe.com/jira/browse/FB-11958" target="_blank"&gt;known bug&lt;/a&gt; which has never been fixed, but I hope it’s been fixed in Flex Builder 4. &lt;/p&gt;  &lt;p&gt;Hope this helps someone having the same problem in the future.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/oP_8X09CwqE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/oP_8X09CwqE/flex-builder-3-changes-not-reflected-in.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/07/flex-builder-3-changes-not-reflected-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-6029026372857835184</guid><pubDate>Sun, 13 Jun 2010 08:54:00 +0000</pubDate><atom:updated>2010-06-26T10:16:56.636+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cloudfront</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">s3</category><title>CDN Sync Version 1.0 Released</title><description>&lt;p&gt;I have just published a small project on &lt;a href="http://codeplex.com" target="_blank"&gt;CodePlex&lt;/a&gt; called &lt;a href="http://cdnsync.codeplex.com/" target="_blank"&gt;CDN Sync&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The primary goal of this project is to provide a set of tools to synchronize local files and folders with Cloud Storage Providers during the Build and Deployment process. &lt;/p&gt;  &lt;p&gt;Using a CDN (Content Delivery Network) for all your static website files should be the default these days if you’re concerned providing the optimal client experience, however deploying these files to your CDN Provider can be a manual process and prone to versioning issues. &lt;/p&gt;  &lt;p&gt;Version 1.0 includes an MSBuild task and support for synchronizing with &lt;a href="http://aws.amazon.com/s3/" target="_blank"&gt;Amazon S3&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pre-Requisites:&lt;/strong&gt;     &lt;br /&gt;Visual Studio 2010     &lt;br /&gt;&lt;a href="https://aws-portal.amazon.com/gp/aws/developer/registration/index.html" target="_blank"&gt;Amazon Web Services Account&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can download the Release from &lt;a href="http://cdnsync.codeplex.com/releases/view/47850" target="_blank"&gt;here&lt;/a&gt; and read the &lt;a href="http://cdnsync.codeplex.com/documentation" target="_blank"&gt;documentation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Future features:      &lt;br /&gt;&lt;/strong&gt;    &lt;br /&gt;Support for Cloud Files     &lt;br /&gt;Support for Windows Azure     &lt;br /&gt;Command Line Interface &lt;/p&gt;  &lt;p&gt;Any questions or issues then please post them to the CodePlex project or comment here. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/PX2hcxGjiT8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/PX2hcxGjiT8/cdn-sync-version-10-released.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/06/cdn-sync-version-10-released.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-8843521184962901253</guid><pubDate>Sun, 16 May 2010 03:29:00 +0000</pubDate><atom:updated>2010-05-16T11:31:55.716+08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">video</category><category domain="http://www.blogger.com/atom/ns#">html5</category><title>HTML5 Video Tag Codec Support</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Recently there was a &lt;a href="http://stackoverflow.com/questions/2755968/h-264-flv-best-practices-for-html/2756022#2756022" target="_blank"&gt;question&lt;/a&gt; asked over on &lt;a href="http://stackoverflow.com" target="_blank"&gt;Stackoverflow.com&lt;/a&gt; regarding best practices around H.264 and the Video Tag.     &lt;br /&gt;The answer with the most votes has IMO provided an inadequate solution and I thought I would take the time to clear this up with a new post.&lt;/p&gt;  &lt;p&gt;Unfortunately and to the frustration of developers that deal with Video content, HTML 5 has &lt;a href="http://www.zdnet.com/news/html-5-drops-open-source-video-codec/318208" target="_blank"&gt;dropped the Codec&lt;/a&gt; as part of the specification leaving the Browser vendors to implement whatever they want.     &lt;br /&gt;However the consensus is to use H.264 with even &lt;a href="http://www.infoq.com/news/2010/04/Microsoft-HTML-5-H.264" target="_blank"&gt;Microsoft adopting this&lt;/a&gt; for the forthcoming Internet Explorer 9.&lt;/p&gt;  &lt;p&gt;Here’s how it stacks in terms of browser support as of writing. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;&lt;strong&gt;Browser&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="133"&gt;&lt;strong&gt;H.264&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="133"&gt;&lt;strong&gt;Ogg Theora&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Google Chrome&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Firefox&lt;/td&gt;        &lt;td valign="top" width="133"&gt;No&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Safari&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="133"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;IE9&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="133"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Opera&lt;/td&gt;        &lt;td valign="top" width="133"&gt;No&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Yes&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;H.264 Only – Chrome, Safari &amp;amp; IE9&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;video controls autobuffer preload height="360" width="480"&gt;&lt;source type="video/mp4" src="http://blog.willbeattie.net.s3.amazonaws.com/framecount.mp4" /&gt;&lt;/p&gt;  &lt;p&gt;If you see this your browser does not support H.264&lt;/p&gt; &lt;/video&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;video &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;480&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;360&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;preload autobuffer controls&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;source &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://blog.willbeattie.net.s3.amazonaws.com/framecount.mp4&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;video/mp4&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;If you see this your browser does not support H.264&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;video&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If you view this on Firefox you will see that their implementation does not ignore the Video tag and display the paragraph tag, instead it shows show the big X. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ogg Theora Only – Firefox, Opera, Chrome&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;video controls autobuffer preload height="360" width="480"&gt;&lt;source type="video/ogg" src="http://blog.willbeattie.net.s3.amazonaws.com/framecount.ogv" /&gt;&lt;/p&gt;

&lt;p&gt;If you see this your browser does not support Ogg Theora&lt;/p&gt;
&lt;/video&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;video &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;480&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;360&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;preload autobuffer controls&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;source &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://blog.willbeattie.net.s3.amazonaws.com/framecount.ogv&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;video/ogg&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;If you see this your browser does not support Ogg Theora&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;video&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H.264 &amp;amp; Ogg Theroa – Firefox, Chrome, Safari, Opera &amp;amp; IE9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;video controls autobuffer preload height="360" width="480"&gt;&lt;source type="video/mp4" src="http://blog.willbeattie.net.s3.amazonaws.com/framecount.mp4" /&gt;&lt;source type="video/ogg" src="http://blog.willbeattie.net.s3.amazonaws.com/framecount.ogv" /&gt;&lt;/p&gt;

&lt;p&gt;If you see this your browser does not support H.264 or Ogg Theora&lt;/p&gt;
&lt;/video&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;video &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;480&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;360&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;preload autobuffer controls&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;source &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://blog.willbeattie.net.s3.amazonaws.com/framecount.mp4&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;video/mp4&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;source &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://blog.willbeattie.net.s3.amazonaws.com/framecount.ogv&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;video/ogg&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;If you see this your browser does not support H.264 or Ogg Theora&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;video&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;If you view this page on all of the aforementioned browsers you will notice that the current Video tag implementations are not very helpful to developers. The ideal would be that the Browser detects the Codec that they don’t support and then fallback to whatever is in the Video tag. &lt;/p&gt;

&lt;p&gt;Now if you are just displaying video content then this doesn’t pose too much of a problem as you can just support a single codec and then fallback to a plug-in based media player of your choice. However if you want to start implementing features using &lt;a href="http://en.wikipedia.org/wiki/Canvas_element" target="_blank"&gt;Canvas&lt;/a&gt; then this becomes a major roadblock. &lt;/p&gt;

&lt;p&gt;The only solution right now is to have an H.264 version and an Ogg Theora version of the same video which is a real PITA especially if you have thousands if not millions of videos to deal with. &lt;/p&gt;

&lt;p&gt;If you do go the route of converting all your videos from H.264 to Ogg Theora then I’d recommended using the &lt;a href="http://v2v.cc/~j/ffmpeg2theora/" target="_blank"&gt;FFMpeg2Theora&lt;/a&gt; convertor as it’s very easy to use. &lt;/p&gt;

&lt;p&gt;Hope this clarifies some of the challenges presented when dealing with Video content using HTML5. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/t08l6D-sQw0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/t08l6D-sQw0/html5-video-tag-codec-support.html</link><author>noreply@blogger.com (Will Beattie)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/05/html5-video-tag-codec-support.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4173999979991669893.post-7603793851386484250</guid><pubDate>Sat, 01 May 2010 07:43:00 +0000</pubDate><atom:updated>2010-09-25T09:47:28.828+08:00</atom:updated><title>Unit Testing Workflow Activities in .NET 4.0</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Recently during a catch up with my buddy &lt;a href="http://blog.keithpatton.com"&gt;Keith Patton&lt;/a&gt; I was (as I tend to do) singing the praises of the Workflow in .NET 4.0. The all important question about Unit Testing support was raised, I tried as best as I could to explain the new In and Out Arguments but I didn’t feel I was convincing enough, so I though I would clarify with a blog post. &lt;/p&gt;  &lt;p&gt;If you developed Workflows in .NET 3.5 then you will be well aware of the lack of Unit Test support which was due to many reasons but mostly in part to the complex Workflow hosting environment.&lt;/p&gt;  &lt;p&gt;When moving to .NET 4.0 Workflow Foundation from .NET 3.5 it pays to be conscious of that fact that there is no longer a distinction between Activities and Workflows. Everything derives from the System.Activities.Activity class. So the definition of a Workflow is just a collection of of 1 or more Activities. &lt;/p&gt;  &lt;p&gt;I have designed a very simple Rental Car Activity which takes the an Applicants age as the input and outputs a True or False depending on the age. &lt;/p&gt;  &lt;p&gt;One of the key benefits of .NET 4.0 is that Activities can be run by passing in an IDictionary&amp;lt;string, object&amp;gt; of your In arguments and the result is an IDictionary&amp;lt;string, object&amp;gt; of Out Arguments, that’s right no more Dependency Properties. &lt;/p&gt;  &lt;p&gt;This is the Workflow Diagram. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xFDmX1zG1zE/S9vbfNoNzRI/AAAAAAAAARw/H-2XVc4QQ9k/s1600-h/workflow%5B3%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="workflow" border="0" alt="workflow" src="http://lh5.ggpht.com/_xFDmX1zG1zE/S9vbf14iRXI/AAAAAAAAAR0/flsJynHQAwA/workflow_thumb%5B1%5D.png?imgmax=800" width="697" height="293" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you can see above there is an Age In argument and an IsApproved Boolean is the Out argument.&lt;/p&gt;  &lt;p&gt;Here is the definition of the Age Check Condition.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xFDmX1zG1zE/S9vbgWcs7JI/AAAAAAAAAR4/rFWAR6jG7LI/s1600-h/activity%5B6%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="activity" border="0" alt="activity" src="http://lh4.ggpht.com/_xFDmX1zG1zE/S9vbg3_JzoI/AAAAAAAAAR8/_N_jA_S3QYs/activity_thumb%5B4%5D.png?imgmax=800" width="525" height="258" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;Now when coming to do the Unit Test the key part of the equation is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.workflowinvoker.aspx"&gt;WorkflowInvoker&lt;/a&gt; class which allows to run any Activity &lt;em&gt;&lt;strong&gt;synchronously&lt;/strong&gt;&lt;/em&gt;.&amp;#160; Specifically the WorkflowInvoker.Invoke method which takes the Activity and IDictionary&amp;lt;string, object&amp;gt; arguments and returns an IDictionary&amp;lt;string, object&amp;gt;. &lt;/p&gt;  &lt;p&gt;And here is the code to test our Activity. &lt;/p&gt;  &lt;pre class="code"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Invoke_RentalCarApprovalWorkflow_WithApplicatantOver25_Should_Return_True()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;age = 26;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;arguments = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;
                                {
                                    {&lt;span style="color: #a31515"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;, age}
                                };


            &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = &lt;span style="color: blue"&gt;new &lt;/span&gt;Workflow.&lt;span style="color: #2b91af"&gt;RentalCarApprovalWorkflow&lt;/span&gt;();

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(activity, arguments);

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull((actual));
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(1, actual.Count);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: blue"&gt;true&lt;/span&gt;, actual[&lt;span style="color: #a31515"&gt;&amp;quot;IsApproved&amp;quot;&lt;/span&gt;]);

        }

        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;Invoke_RentalCarApprovalWorkflow_WithApplicatantUnder25_Should_Return_False()
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;age = 24;

            &lt;span style="color: blue"&gt;var &lt;/span&gt;arguments = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;
                                {
                                    {&lt;span style="color: #a31515"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;, age}
                                };

            &lt;span style="color: blue"&gt;var &lt;/span&gt;activity = &lt;span style="color: blue"&gt;new &lt;/span&gt;Workflow.&lt;span style="color: #2b91af"&gt;RentalCarApprovalWorkflow&lt;/span&gt;();

            &lt;span style="color: blue"&gt;var &lt;/span&gt;actual = &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(activity, arguments);

            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull((actual));
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(1, actual.Count);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: blue"&gt;false&lt;/span&gt;, actual[&lt;span style="color: #a31515"&gt;&amp;quot;IsApproved&amp;quot;&lt;/span&gt;]);

        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;It’s really that simple. &lt;/p&gt;

&lt;p&gt;Drop me a line if you have any questions or problems implementing this. &lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Till next time. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/willbeattiesblog/~4/dTEbSDZd6kw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/willbeattiesblog/~3/dTEbSDZd6kw/unit-testing-workflow-activities-in-net.html</link><author>noreply@blogger.com (Will Beattie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_xFDmX1zG1zE/S9vbf14iRXI/AAAAAAAAAR0/flsJynHQAwA/s72-c/workflow_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.willbeattie.net/2010/05/unit-testing-workflow-activities-in-net.html</feedburner:origLink></item></channel></rss>
