Automapper and Silverlight 4? Yes Please!

I’m working on a fairly complex Silverlight application (Entity Framework 4, Prism/Unity, WCF RIA Services) and suddenly ran head-first into a need for some object mapping.  I haven’t done this before, but I had heard of Automapper so I Googled it and read the documentation.  Perfect!

Then I read up on the Silverlight Automapper release.  Uh-oh… last built in February 2010.  For Silverlight 3.  Curses…

I had two options at this point.  Do my mapping at the server side using the “regular” Automapper, or dig in and make Automapper Silverlight Edition work for me.  I downloaded the source, thinking I could (as I had done before with other projects) simply change the compilation target to Silverlight 4 and recompile.  Tried this and BAM!  No worky.  The version of mscorlib is 2.0.

Tried removing mscorlib and re-adding it from the Reference Assemblies.  BAM!  Visual Studio bug.

OK, so this will have to be a new project:

  1. File-New Project/New Silverlight Application.  Call it Automapper.Silverlight4.
  2. Copy the “lib” folder from the Automapper source into the root folder of your new build
  3. Add Reference to Castle.Core and Castle.DynamicProxy2 from the lib folder (don’t worry about the net3.5 folder, still works)
  4. Right-click the project and select Add Existing Item
  5. Navigate to the Automapper source and select all files in the root, then select Add As Link from the dropdown.
  6. Create Internal and Mappers folders and repeat the above steps for those folders in the Automapper source project.
  7. Delete links to DataReaderMapper and ListSourceMapper under Mappers folder (not supported by Silverlight.)
  8. Build!

It works!  I now have Automapper working in a Silverlight 4 application.  I’m sure I’m not the first to try this, but it’s good to know it’s possible.

What’s the big deal with RIA?

Rich Internet Applications are about more than visual bling and animations. It’s the beginning of the end of the “traditional” desktop application. I’m really excited about RIA in general, because I think it portends big changes in the way applications are developed and delivered. How exactly will that change happen, and what will it be? That question begs another question: what is the point of RIA, and what’s all the buzz about?

In a nutshell, RIA applications are client apps that are delivered over the web. They run in a sandboxed runtime environment on the client, and get their data mostly through services hosted in the cloud. So what’s the big deal?

The runtime is the big deal. With a sandboxed runtime environment, you get a few things for free. Most important among these is security and cross-platform compatibility. Whether it’s an AIR or Sliverlight applicaiton, it will (theoretically) run anywhere the environment is installed. No worrying about HTML/CSS formatting or quirky browser implementations- if the environment is there, it runs. You also get the speed benefit of moving processing back to the client. No more waiting for IIS/Apache to process your request- RIA apps run locally. As a developer you also get the rich UX capabilites, which could be the most important aspect of any application.

So why are Microsoft and Adobe beating a path to developers’ doors? Why do they care about RIA? Here’s a tweet from Jeff Atwood:

“When everything is a web app, maybe we’ll have new operating systems…”

This simple, casual comment sums it up. Eventually, just about every application will be delivered over the web. Sticking in a CD or downloading an installer is just so 2005. The winner(s) in the RIA platform space will offer to developers a potential audience of millions of users, regardless of OS. All this with practically free delivery over the web. That’s a big deal.

As the move to RIA continues, “web application development” will mean less HTML and more XAML/MXML. Browser compatibility will be less of a concern. Web developers will rely on the platforms to handle runtime compatibility while they focus on application development (as it should be!) A single codebase targeted to a RIA platform can support a potentially huge audience, making development cheaper and reducing testing cycles.

RIA is still in its infancy. So far I see way more potential than real applications, though that’s changing fast. I think Adobe’s AIR is currently beating Silverlight for features overall, but I see that gap closing with each release of Silverlight. Over time, I see both platforms effective across just about every major market OS, including mobile. As Adobe and Microsoft figure out how loose they can safely make the sandbox, more powerful features will be offered.

Eventually, I see a time when users spend more total minutes interacting with RIA applications than they do their OS. I see fully-featured RIA “desktop replacements.” Imagine booting up any old OS, visiting a website, and getting a completely different experience wherever you are. Store your data in the cloud, run a RIA OS, and the local OS suddenly doesn’t matter so much. Call it a “Virtual OS” or a “Cloud OS” or whatever you like, it’s coming fast.

The one thing I can say for sure is this: no one can say with certainty what RIA will mean over the long term, but it smells to me like opportunity. Shifts like this come maybe once a decade. It’s not often you can see the swell of a new meme ahead of its crest. Getting into RIA development is easy and getting easier, so jump in! The water’s great!

Silverlight Research Summary

So, I made it through Step 2: Read of my Learning Process 2.0 for Silverlight. Here is the product of that process.

Prologue: There is a really cool demo of Silverlight capabilities here.

What is Silverlight?

Remember “Write Once, Run Anywhere?” This lofty goal has been promised before <cough Java cough>. It’s still a desirable thing, to be sure: just ask any developer that still has to code webpages to look decent on IE6.

A new generation of technologies is beginning to deliver on the multi-platform promise of old. Silverlight is Microsoft’s entry into that fray. The Silverlight runtime is a subset of the .NET Base Class Library, runs on PC and Mac, and runs in all the major browsers including IE, Firefox, Safari, Opera, Chrome, and more.

Silverlight was born as “WPF/E”, which stands for Windows Presentation Foundation/Everywhere. WPF and Silverlight are both Microsoft’s latest User Interface technology offerings. Both are based on eXtensible Application Markup Language, aka XAML. The difference between WPF and Silverlight is in delivery: WPF is a desktop technology. Silverlight is a Rich Internet Application framework for delivery of rich user interfaces via the web.

No discussion of Silverlight is complete without mentioning Flash. Yes, Silverlight competes with Flash. Directly.

  1. Both Flash and Silverlight run in a sandboxed environment on the client.
  2. Both offer vector graphics and media (audio/video) capability.
  3. As of Silverlight 3.0, both support an out-of-browser running mode (Adobe AIR allows Flash/Flex programs to run locally outside a browser.)
    1. The primary difference between them is that Flash uses Actionscript, and Silverlight is based on .NET, which means Silverlight applications may be developed in any .NET-compliant language. These include VB.NET, C#, and with the Dynamic Languages support in Silverlight, IronPython and IronRuby.

      Browser Integration

      A Silverlight application may be embedded into a webpage using the Silverlight ActiveX control and the <object> notation, or by using javascript. A javascript bridge (HTML Bridge) between Silverlight applications and the hosting page allows javascript to call into the Silverlight app, and managed Silverlight code to call out to javascript functions declared in the hosting page.

      XAML

      XAML stands for eXtensible Application Markup Language. It is an XML-based language for describing visual elements of a User Interface.

      Think back to the days of VB6: the UI was all tangled up in the code. Then came .NET, and for some time the UI was all tangled up in auto-generated “designer” code. Now comes WPF, Silverlight, and XAML. Using XAML, the UI definition is completely separated from the programming logic. XAML pages declaratively describe an object graph. Parsing a Silverlight XAML page results in the instantiation of that graph and the rendering of the user interface it describes.

      Dynamic Language Support

      Dynamic Languages in Silverlight allow IronPython and IronRuby programs to manipulate and interact with the user interface in the same way as C# or VB.NET. This opens up Silverlight to Python and Ruby developers. The DLR Console Sample demonstrates another capability: interacting with a running Silverlight application in real time using code.

      Layout System

      The Silverlight layout system determines how visible elements of an application are positioned relative to the application host and each other. Several layout controls are included with Silverlight, including Canvas, Grid, and StackPanel, to name a few.

      Controls are laid out by the engine using inherited Measure and Arrange methods that cooperate to determine how much visible area a control wants, and how much it gets as a result of the overall layout of all visible elements.

      Controls

      Silverlight 2.0 introduced a library of ready-made controls, such as TextBlock, TextBox, ComboBox, etc. MSDN has a handy directory of controls.

      Silverlight controls are “look-less” in that the code that defines their behavior contains absolutely nothing about how they appear visually. The visual appearance of controls, including custom controls, is defined entirely in XAML. The .NET class that implements the control is referred to as a “control contract.”

      Just as with .NET Winforms and ASP.NET controls, WPF/Silverlight controls can be customized or created from scratch. Customization of controls in Silverlight is quite different, however. Winforms and ASP.NET controls can be subclassed and then customized. Silverlight control customization involves replacing the ControlTemplate of a control. This allows a developer to completely replace the visual behavior of an existing control.

      Common content may be shared across controls using a DataTemplate. This supports adding a common icon to a custom “submit” button, for example.

      Networking

      Communicating with the cloud in Silverlight presents several security challenges. Silverlight applications cannot freely communicate with just any service over any port; there are restrictions to prevent security threats such as malware, viruses, and spyware. Depending on configuration, communication is either handled for the Silverlight application by the browser, or the Silverlight client itself handles HTTP/HTTPS communications. The latter configuration is useful for RESTful communications or when the developer wants to handle cookies manually.

      The standard class for network communcation is WebClient. WebClient has asynchronous methods for writing and reading to a network stream. The HttpWebRequest and HttpWebResponse classes contain methods for more granular communications, including the ability to manipulate HTTP headers. Silverlight also supports Sockets for low-level TCP communications.

      The security model Silverlight uses allows minimally-restricted communication between the hosting domain and a Silverlight application. If a Silverlight app wants resources (i.e. files, read/write to a service) from another domain, however, a cross-domain policy file must be present on that domain. Flash/Flex/AIR applications use a similar security model, and Silverlight can read Flash cross-domain policy files. The policy file is an XML-formatted file that indicates what services and resources are accessible, and to whom.

      Data

      This was a source of confusion for me when I first started with Silveright. It’s important to remember that Silverlight apps run in the browser. This makes them more like Winforms apps than ASP.NET apps. Silverlight apps get their data over the wire just like any other desktop application. What does a Winforms app do when it needs data from the cloud? It uses a webservice.

      Silverlight apps can get their data over the wire via RESTful or SOAP-based services like WCF. Microsoft provides some help for data access in the form of ADO.NET Data Services (formerly Astoria) and .NET RIA Services.

      Here I am going to punt and guide you to the best authority I’ve seen on the difference between these options: Shawn Wildermuth.

      Media and Animation

      Silverlight’s Animation system is centered on the Storyboard control and the Animation controls. “From-To” animations including DoubleAnimation, PointAnimation, and ColorAnimation are used to animate double, point, and color-type properties of a control. These animations have keyframe-based companions (DoubleAnimationUsingKeyFrames, PointAnimationUsingKeyframes, you get the idea) that use keyframing to perform the animation. Keyframing is a technique by which frames are interpolated between key points that are set in an animation.

      Bonus: DependencyObject and DependencyProperty

      DependencyObjects and DependencyProperties were not in the mind map, but they are important enough that they probably should have been, so I’ll go into them briefly here.

      Silverlight controls need lots of dependencies on each other for things like animation and layout. This requires more than the common model of using private fields to back public properties. DependencyProperties are like super-properties. When the values of a DependencyProperty are getted (is that a word?) or setted (again?) the internal implementation of DependencyObject (DependencyProperties’ base class) allows other things to happen, like notifying an ObservableCollection that a member has been updated (this is databinding), or animating a property of a control from outside the scope of that control.

Deconstructing My Learning Process

Lately I’ve been doing some self-examination of my learning process.  With Microsoft releasing so much new technology, including .NET 3.5, Silverlight, Azure, and soon .NET 4 (just to name a few) in rapid succession, there is a TON of new stuff to learn.  The learning process is fun for me.  I really enjoy picking apart a new technology, figuring out what it can do that no one has done yet.

I tend to follow the same loosely defined process when I’m picking up something new:

  1. Decide I want to change the world with some technology (often the flavor of the day: Azure, LINQ , Silverlight, etc.)
  2. Do a blizzard of Google searching
  3. Save a bunch of links (Delicious, private wiki, etc)
  4. Add all of that domain’s guru’s blogs to Google Reader (ScottGu, Wildermuth, etc)
  5. Add the StackOverflow RSS for that subject to Google Reader (I currently watch Silverlight and Entity Framework-tagged questions, it’s very cool!)
  6. Read a bunch of “how-to” walkthroughs
  7. Download code samples that demonstrate the bits and bobs I want to learn
  8. Go to town with VS.NET

I suspect this is a common process for many people.  It has occurred to me that being more aware of this process might help me to improve it.  I’m currently in the process of a deep dive into Silverlight.  Silverlight is such a humongous subject unto itself that I find myself spending too much time spinning my wheels.  Therefore, in the interest of improving my learning process and making it more efficient, I’ve decided to deconstruct it here for all to see!

Strengths and Weaknesses

Here is what I like about my process:

  • Gathers lots of reference material
  • Identifies authoritative sources for information
  • Follows others work in the domain (StackOverflow, Blogs, Code Samples)

Here is where I think my process can be improved:

  • Disorderly
  • Too task-focused
  • Wastes too much time on narrow subdomains

My Current Process

I’ll use my Silverlight research to demonstrate my current modus operandi.  I’m really jazzed about Silverlight, so I’d like to learn as much as I can.  I want breadth and depth.  I started with #2 of Dave’s Way to Learn Stuff, so I went to Google:

The first link is the official Silverlight Get Started page.    It’s a good start.  I see all the tools I’ll need to get rolling.  I also see:

  • Tim Heuer’s “hello world!”  Silverlight screencast
  • ScottGu’s series on Silverlight
  • Lynda.com training videos

I looked at some of these videos and articles, but not all, and not in any particular order.  My current process is not that orderly.  I tend to start off with an idea of what I want to accomplish, then set out to achieve it by targeting the specific elements I need to “Make It Work.”  This is one of the major flaws in my process.  I get so excited about creating something that I absorb the information I need in a disorganized, scattershot fashion.  In my impatience, I go down a single rabbit-hole without building the larger picture around me first.  The return on my time investment yields, at best, a narrow task-oriented understanding.

Dave’s Learning Process 2.0

Step 1: Mind Maps

What to do?  I need to be patient enough to build a comprehensive, 10,000 foot-level understanding of the domain before I dig deeper. If you’re like me, you want the big picture…


Click to enlarge

I ran across the idea of Mind Maps some time ago, but only recently realized their potential.  I’m a visual kinda guy.  You can stand a talking head in front of me for hours and I’ll absorb maybe 30% of what he/she says.  Sit me in front of a cool Discovery program with lots of pretty graphics, and I’m a sponge- I’ll memorize 80% of the stuff.  Mind maps are an excellent way to create a visual representation of a subject.  They help synthesize domain information into a comprehensive mental model.

The mind map above took me less than twenty minutes to build.  I stole borrowed the structure right out of the MSDN Silverlight Roadmap.  It’s not complete, but it doesn’t have to be.  It covers the major aspects of Silverlight, so I have my 10,000-foot overview.  When I learn something new about Silverlight, I’ll know where to plant it in my mental garden.

Creating your own mind map of a subject is a great first step to learning it.  If breadth and depth is what you want, you can round-robin each major trunk, “drilling downward” into the subject, rather than inadvertently falling down one rabbit-hole to the exclusion of all other subdomains.  Using a mind map, you’re in better control over your research process.  If you’re only interested in one sliver of a domain, such as Silverlight Media and Animation, that’s fine, but I still believe the mind map is useful.   It helps you understand how subdomains relate to each other.  Notice in my Silverlight Mind Map how DataGrid straddles Data and Controls.  If you want to understand DataGrids, you’ll have to learn at least a little about how Silverlight handles Data.

Read, Follow, Create, Invent

Now that my mind map is created, I can build the foundation. My past research process has been driven by impatience- I want to get something done NOW! This has lead to a false economy of time investment. From now on, I will take the time to ingest the basics first. Ironically, I think this will save me time in the long run. I will spend less time looking things up and cross-referencing if I read up on the essentials first. I can also rely on the mind map to let me know how far I’ve gone and how far I have left to go. This will keep me from feeling that the foundational learning is an endless, pointless process… the feeling that has historically kept me from taking the time in the first place!


Step 1: Read

Let’s go back to the MSDN Silverlight Roadmap. I pulled eight major trunks out of the Roadmap and added it to my mind map. Each of those trunks has a dedicated top-level page on MSDN. This just isn’t a lot of reading. Once I’ve read each of these, I can make notations on my mind map, calling out areas where I want to dive deeper. I won’t spend more than say, fifteen minutes on each trunk before I move on to the next one.

Step 2: Follow

Now it’s time to do a little trying out by following simple examples. I’ll build a test project, and add a page for each of the major trunks. Here I will try out little bits and pieces of each subdomain. Nothing fancy, nothing complex, nothing integrated. Just tiny little examples of each subject. Look for the most basic how-to code samples for each subdomain and just copy and paste.

Step 3: Create

This is the stage where some creativity comes into play. As a few “what-if” questions about the examples you’ve built, and start to experiment with tweaks and modifications. Form and test some theories about the way the features work by themselves and together. Try combining features from related subdomains in a limited way until you have a feel for how they interoperate.

Step 4: Invent

Now we’re ready to build a real application. Using elements from several different subdomains, build something simple but useful. My first full Silverlight app will be… tada! a Sticky Note application. Stop the presses.

Lab Coat Time

Let me be clear: this is not wisdom from on high. It’s not the new bestselling productivity book. It’s an experiment- my experiment. I have a good feeling about it because it feels… weird, heavy somehow. I know that has to be a good thing because anything better than my current way of doing things will be outside my comfort zone. Therefore, a little discomfort is probably a good sign!

So, my next step will be to start with Read. I will dive into the MSDN Roadmap and go from there. I will dutifully report my progress, so watch this space for updates and code samples as I forge ahead! If this works as well as I hope it does, expect to see more open studying for lots of other goodies. Stay tuned!

DS

Silverlight: Upload and Display Image

I’m working on a little pet Silverlight project and thought I’d share a quick solution. I wanted to see if I could upload and image to the server, then turn around and download that image and display it. This works in Silverlight 3.

The XAML:

<UserControl x:Class="ImageEditor.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" MouseMove="UserControl_MouseMove">

    <Grid x:Name="LayoutRoot" Background="Azure" Width="800" Height="600">
    <Image x:Name="MainImage" Source="images/image.jpg"  Width="300" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
    <Button x:Name="UploadImage" Click="UploadImage_Click" Content="Upload"></Button>
    </Grid>
</UserControl>

The Code:

private void UploadImage_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = false;
            dlg.Filter = "All files (*.*)|*.*|PNG Images (*.png)|*.png";

            bool? retval = dlg.ShowDialog();

            if (retval != null && retval == true)
            {
                UploadFile(dlg.File.Name, dlg.File.OpenRead());
                StatusText.Text = dlg.File.Name;
            }
            else
            {
                StatusText.Text = "No file selected...";
            }
        }

        private void UploadFile(string fileName, Stream data)
        {
            string host = Application.Current.Host.Source.AbsoluteUri;
            host = host.Remove(host.IndexOf("/ClientBin"));

            UriBuilder ub = new UriBuilder(host + "/receiver.ashx");
            ub.Query = string.Format("filename={0}", fileName);
            WebClient c = new WebClient();
            c.OpenWriteCompleted += (sender, e) =>
            {
                PushData(data, e.Result);
                e.Result.Close();
                data.Close();
            };
            c.WriteStreamClosed += (sender, e) =>
            {
                LoadImage(fileName);
            };
            c.OpenWriteAsync(ub.Uri);
        }

        private void LoadImage(string fileName)
        {
            //
            // Creating WebClient object and setting up events
            //
            WebClient downloader = new WebClient();
            downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
            //downloader.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloader_DownloadProgressChanged);

            //
            // Specify Image to load
            //
            string host = Application.Current.Host.Source.AbsoluteUri;
            host = host.Remove(host.IndexOf("/ClientBin"));

            fileName = host + "/images/" + fileName;
            downloader.OpenReadAsync(new Uri(fileName, UriKind.Absolute));
        }

        void downloader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            //
            // Create a new BitmapImage and load the stream
            //
            BitmapImage loadedImage = new BitmapImage();
            loadedImage.SetSource(e.Result);

            //
            // Setting our BitmapImage as the source of a imageControl control I have in XAML
            //
            MainImage.Source = loadedImage;
        } 

        private void PushData(Stream input, Stream output)
        {
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
            {
                output.Write(buffer, 0, bytesRead);
            }
        }

The Handler (receiver.ashx):

[WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class receiver : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            string filename = context.Request.QueryString["filename"].ToString();

            using (FileStream fs = File.Create(context.Server.MapPath("~/images/" + filename)))
            {
                SaveFile(context.Request.InputStream, fs);
            }
        }

        private void SaveFile(Stream stream, FileStream fs)
        {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
            {
                fs.Write(buffer, 0, bytesRead);
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }

Credit is due to Nipun Tomar for the file uploading stuff and Kirupa.com for the help with loading images on demand.  You can get the details on how this code works from those two links.  Enjoy!

Follow

Get every new post delivered to your Inbox.