desc="My angle on brackets" />

  • The Third Industrial Revolution - Fueled by The Cloud

     It's so early in the days of cloud computing. Many haven't even started to realize the magnitude what this shift could be.


    It's the change from custom to standardized… Yes, there's the often cited analogy to the evolution of power supply. From having your own water wheel to plugging into the electric grid. My current favorite analogy is clothing. People had clothing for the longest time, they still do, but lots of things have changed since a few hundred years ago when people either made their own, or they could afford a tailor to have their clothes tailor made.


    Because of that, most people didn't own more than a few pieces of clothing, but the few tailored ones they owned fit very well. With increasing industrialization came clothes in standard sizes. It was more economical for manufacturers to make just a few sizes. Over time, even the number of sizes went down. Some companies only make S, M, L and possibly XL. Why? Because it's even more economical to make as few sizes as possible.


    Cloud computing is going to put the world of computing through the same evolution. It takes computing to the industrial age. We're moving past the times where environments were made from scratch and purpose built. In the industrial age, it's about buying mass-market products, manufactured to fit "good enough" for many but not fitting perfectly for just one use.


    Clothing brands that have more differentiated sizing today are usually more expensive. They have to pass on the higher manufacturing cost and cater to customers that prefer better fitting clothes over cheap ones. You can also still got to a tailor and get custom made clothes, they fit great, but they are far more expensive than buying a standard size.


    The analogy seems to hold when you explore deeper. Custom clothes never went away. Special purpose clothing is still not mass-produced and sold at Walmart. In fact, department stores, high-end boutiques and custom tailors are still around.


    Computing will undergo a similar evolution and thus fuel the Third Indstrial Revolution. On-prem computing is not going away, but there are many the cases where "good enough, easy and cheap will do". Those cases will go to the cloud. In the cases where you need something special, you go to Nordstrom for clothes, you'll stay in your own computing environment for computing.


    What's uncertain is the mix between on-prem and the cloud? I would think that Kohl's or Target sell a whole lot more clothes than Nordstrom or Saks. Target's price points and the ubiquity of their stores make buying clothes cheap and easy. Overall, Target's annual revenue is about 70x the revenue of Nordstrom. While they're both retailers, the experience and the products don't compare. They address different scenarios. Sometimes cheap and easy is sufficient. In fact, I may sacrifice some nice-to-haves when I get something cheap with a 5 minute trip around the corner.


    In the world of cloud computing, I don’t get the same high-performance, highly tuned servers I can put into my own data center - BUT I don't need those in every scenario. In many cases, an IaaS environment with all the constraints of a standardized environment will be good enough. With the right architecture, an cloud environment can still deliver well performing and highly scalable solutions. In some cases however, the cloud doesn't meet performance or scale requirements and then I have the option to engineer and environment that will meet my needs.


    If the analogy holds then cloud computing is just as transformational as the introduction of standardized clothing sizes. When S, M and L came around, it wasn't about giving people the ability to express themselves with wearing different styles! It was about meeting the scalability needs of war that needed to put uniforms on soldiers.


    It wasn't about starting a fashion industry that has to create new styles every year. It wasn't about lifestyles and creating the job of the super model, but the new means of mass producing clothes gave rise to new business models, new industries and impacted the lifestyle of billions of people. 


    Cloud computing started with making computing more affordable and scalable. What's going to happen when computing is cheap, easy and ubiquitous?


    It's very early in the days of cloud computing. I don't think I've grasped the magnitude yet, but we're seeing the early signs of transformation. New business models are emerging, new content offerings … new ways to build companies.


    It's going to be exciting times.



  • Cloud is the Next iPhone (for IT)

    Then on January 9th, 2007 the world changed. Not just the technology world, but the world as we knew it. Yes, Steve Jobs only showed a product, the first iPhone, but what he really showed the world what it's like to be connected and have access to the internet at all times.


  • Silverlight 3 – How to access peripherals

    The previous post on Silverlight 3 for kiosk apps outlined some architecture options how you can build Silverlight applications with access to peripherals. This follow up post goes into more detail on the implementation.

    I strongly encourage you to consider WPF, ClickOnce and POS for .NET as the foundation of your application before you go ahead building these types of applications. The major benefits of Silverlight are the small run-time and the cross-platform availability. Chances are that cross-platform is not necessary in a kiosk environment. The small runtime may not be a big advantage if you are deploying a local application, if you’re deploying, you may as well deploy the full .NET runtime. In fact, the lean runtime may be a disadvantage since it’s lacking functionality available in the .NET libraries. ClickOnce may provide similar benefits as a web deployment of Silverlight.

    Now … if you’re still reading, you probably determined that Silverlight is the way to go.

    The solution is based on several key features in Silverlight

    • Hosting Silverlight in a custom container via the hosting API – introduced with Silverlight 1
    • Scripting Silverlight applications – introduced with Silverlight 1
    • Local messaging between Silverlight applications – even across different containers, first introduced with Silverlight 3

    Let’s take a look how we can string these together to build a solution that maintains the integrity and protection of the Silverlight sandbox, but also let us get to local computing resources and maintains the benefits of Silverlight development and deployment.

    First, you can host Silverlight applications not only in a web browser, but also in a custom application container via the Hosting COM API. You’re in for a blast from the past since some experience with C++ and COM is definitely required to get this to work. There’s a sample for Silverlight Alternative Hosting on MSDN. You save yourself a lot of time and effort compared to implementing the various COM interfaces if you just download the sample and start from there.

    Custom Silverlight Hosting

    First, you decide how you’re going to load the Silverlight application in the custom container. You could load a .xap from the local disk, or you could local the .xap application over the web. Loading from a URL over the web preserves some of the deployment flexibilities of a browser app, but if you’re running an application without a network connection, loading the application from a http URL may not be an option.

    Loading a XAP from from a URL, either a file:/// URL or an http:// URL will work. To load the Silverlight application, you pass the URL to the application as a named Source property in the PropertyBag during control activation (I didn’t think I would ever have to write about ActiveX control activation again). The TutorialXcpHost application from the MSDN sample makes this very easy. It includes a XcpControlHost helper class with the SetSource method. You call SetSource before activating the control:

    int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR lpCmdLine, int nShowCmd) 
       return _AtlModule.WinMain(nShowCmd);

    Even when running in a custom host, Silverlight is still validating zones and enforces some cross-domain security. If you’re loading additional application data or resources, then base URL and zone (file:/// or http://) need to match. You can play some trickery by implementing the container’s IXcpControlHost::GetBaseUrl() method to return a matching zone, but it’s safer to play by the rules and comply with Silverlight’s security policies. after all, they’ve been put in place for good reasons.

    So far, we can load a Silverlight application into a custom container, that provides more flexibility than a browser. For example, the custom container can communicate with other local resources or devices. Next we need to enable communication between the container and the Silverlight application.

    Defining an interface from Silverlight to the Custom Container

    A Silverlight application can expose an interface to scripting engines to allow integration with the host. For example the javascript engine in a browser can get and set properties of a Silverlight application and invoke methods exposed to script. The Silverlight piece of the code is very simple.

    1. You define a class that represents your scripting interface and mark the class with the [ScriptableType] attribute.
      public class MyScriptableObject
      // ... 
    2. In that class, you mark methods you want to expose to the scripting engine with the [ScriptableMember] attribute.
      public void ShowMessage()
      // ...

      Note: Properties and Methods must be public, or discovering the Method with GetIDsofNames will return E_FAIL.

    1. You register an instance of the ScriptableType with the Silverlight runtime after the application starts up by calling RegisterScriptableObject. It’s very important to note that you have to call RegisterScriptableObject after runtime and application are intialized, not during the MainPage’s constructor or in InitializeComponent(). Scripting will not work correctly if you register the object too early.
      private void Application_Startup(object sender, StartupEventArgs e)
          this.RootVisual = new MainPage();
          HtmlPage.RegisterScriptableObject("MyReceiver", new MyScriptableObject(this.RootVisual as UserControl));

    Now the Silverlight application exposes an interface for the container to call. Since this application is running in a custom container, the container can call into the application in response to an event from a card reader for example.

    Calling the Silverlight interface

    The HTML bridge is part of Silverlight to integrate with browser’s java script engines. That doesn’t mean you can’t make use of it from other containers though. We’re calling the scriptable objects from the C++ container. It’s a little bit cumbersome in our scenario since you have to deal with late bound objects through COM interfaces, but the sample code may help you out a little bit.

    Let’s look at the important pieces. The host for the Silverlight application must allow for access to objects that the  Silverlight application registered with the scripting bridge. IXcpControlHost::GetHostOptions() gets called during activation of the control by the hosted Silverlight runtime to find out which features the host allows. The options returned to Silverlight control must include XcpHostOption_EnableScriptableObjectAccess;

    STDMETHODIMP CXcpControlHost::GetHostOptions(DWORD* pdwOptions)
      *pdwOptions = XcpHostOption_EnableCrossDomainDownloads | XcpHostOption_EnableScriptableObjectAccess;
      return S_OK;

    Without the option set, attempts  by the container to obtain a reference (the DISPID as we’ll see shortly) will fail. RegisterScriptableObject, however, succeeds.

    Getting to the registered object requires some understanding of COM. If you never had to deal with IUnknown and IDispatch, you may want to take a quick look at the COM reference.

    The scriptable objects are a accessible from the Silverlight control’s Content Interface. Like all other late bound objects, properties and method on the Content object is available via IDispatch, which turns the inconspicuous lines of javascript:

    slCtl  = sender.get_element();

    into the slightly more verbose C++ equivalent:

      _axWindow.QueryControl(IID_IXcpControl, (void**)&pxcpControl);
      HRESULT hr = pxcpControl->get_Content( &pContentDispatch );
      BSTR name = L"MyReceiver";
      hr = pContentDispatch->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispatchID);
      hr = pContentDispatch->Invoke(dispatchID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &params, &varResult, NULL, NULL);
      pScriptableObjectDispatch = varResult.pdispVal;
      name = L"ShowMessage";
      hr = pScriptableObjectDispatch->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispatchID);
      hr = pScriptableObjectDispatch->Invoke(dispatchID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);

    Let’s examine those lines a little bit more closely. First you get a reference to the Silverlight control. From the control you go to the control’s content. There’s an implicit assumption here that you don’t access the Content until after the VisualTree is constructed.

    From the content, you get the ScriptableObject by the name passed to RegisterScriptableObject in the Silverlight application. Then finally, very important(!), you ask the ScriptableObject for its default dispatch interface, from where you get method or property references, which you can invoke via IDispatch::Invoke.

    Now you have everything in place to listen to events from peripherals and pass them on to a Silverlight application running inside the custom host.

    Communication between Applications

    If you need run the Silverlight application running in a browser, then you can build a bridge from the custom host that communicates with the browser application with the silverlight application communication feature introduced with Silverlight 3.

    Two applications can communicate with the LocalMessageSender and LocalMessageReceiver objects. If you need to forward local events to a browser application, then the browser application would start listening to messages.

    Setting up Sender and Receiver is straight forward. The receiving applications starts the listener:

    LocalMessageReceiver receiver = new LocalMessageReceiver(     
        "Receiver Name",    
        ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain  );
    receiver.MessageReceived += ( object sender, MessageReceivedEventArgs e ) =>
            items.Add( new ListItem() { Text= e.Message + " " + DateTime.Now.ToLongTimeString() } );

    and the sending application sends to a receiver with the registered name:

    LocalMessageSender msgsender = new LocalMessageSender(    
        "Receiver Name",     
        System.Windows.Messaging.LocalMessageSender.Global );
    msgsender.SendCompleted += ( object sender2, SendCompletedEventArgs e2 ) =>
        MessageBox.Show("Result: " );

    MSDN has a good overview of local messaging in Silverlight, including some advanced features like sending complex XML messages and troubleshooting.

    What’s important to note, is that the BaseUrl of the sending application has to match the BaseUrl of the receiving application. Even setting the receiver options and disabling zone checks are not sufficient for the receiver to process incoming messages. You may have to play some more tricks in the host if you’re not planning on loading the sending application from the same site.

    For example, you could intercept the download request in IXcpControlHost::DownloadUrl() to load the .xap from other locations.

    Closing Words

    The upcoming Silverlight 4 release is going to simplify the architecture for out-of-browser scenarios. Silverlight 4 trusted applications can communicate with COM servers directly, which eliminates the need for hosting a Silverlight application in a custom container to get access to local resources. You still need the custom container bridge if your browser application needs access to devices and other local resources.

    I’m planning a follow up post discussing the Silverlight 4 option. It’s going to be a little bit before SL4 ships – Scott Guthrie mentioned H1 2010 as the target timeframe during his PDC Day 2 keynote. It’s good to have a working option with Silverlight 3 before that.

    And finally, the big thank you to Ashish, who patiently answered my questions about the COM APIs while I was looking for the magic combination ;)


  • What’s so old-school about text based programming?

    Computerworld posted this piece that Microsoft developers are using text editors for development. What’s so old-school about that? What I mean really? Coding in text editors is not a trend among the grey-hairds like Lewis suggested on an internal thread. Text based tools are all the rave with the next generation of developers. I mean people that look like the Mac guy in the Apple commercials.


  • Silverlight 3 for Kiosk Apps? Of Course!

    Several of the customers I work with are looking to build kiosk or point-of-sale applications with Silverlight. The ease of deployment with browser-based Silverlight applications is definitely appealing. Sharing applications or components between customers’ kiosks and web sites is another appealing reasons to go with Silverlight. This post outlines the architecture decisions between Silverlight and WPF and presents architecture options for Silverlight based solutions. A follow up post will discuss the Silverlight implementation details.