Tuesday, January 29, 2013

Nothing great was ever achieved without enthusiasm...

,
Over the past month I have had the opportunity to give some thought to what I wanted to accomplish this year in my life, career, and health. And during those times of thought I have often gone back to a speech I listened or re-listened to by the late Jimmy Valvano.

Jimmy V was a great college basketball coach and was unfortunately diagnosed and later passed away from bone cancer. But shortly before his death he gave a riveting speech at the 1993 ESPN ESPY Awards. There are some great things he said, but one statement lost in many outtakes that stuck with me was

"Nothing great was ever achieved without enthusiasm" ...Ralph Waldo Emerson

I think about that statement and how it relates to life, but also how I approach code, software development and teaching. Enthusiasm is the name of the game.  I'm passionate in how I present it, teach it, talk about it and code it. 

The question I have always wondered is how can the few of us who think this way make that feeling contagious? Spread that disease?

I know how I feel after taking a good 5 mile run or so and beating a goal or my last time thinking, "hell yes!" and that's the same feeling I get when a project is complete or I inspire a developer to do something different or try a new path and then later they tell me "thanks, just what I needed".

Recently, after a .NET User Group meeting I sat and had a beer with a few friends from the group and we had this very discussion and the conversation was really good.  I heard stuff like...

"It's not their project...."

"...making the other guy money, why be passionate"

"...some companies are better at making their devs feel ownership..."

What are your thoughts?  What can make you more enthusiastic or pump up that 9-5'er you know at your office?

Start the conversation....
Read more →

Monday, January 28, 2013

Portable MVVM Light - Move Your View Models : Part 2

,
In the first part I covered how to get the initial project setup and share the ViewModels and ViewModelLocator between a Windows Phone 8 project and a Windows Store Application.  In this post, I'll add a DataService and a Model class that will be used to get the most recent posts from the Windows Phone Blog and display the results.

Adding DataService and Async to Portable Class Library

The purpose of the DataService in the context of this project is to retrieve the RSS feed from the Windows Phone Blog (http://blogs.windows.com/windows_phone/b/wpdev/rss.aspx) using the async methods available in the 4.5 Framework, return a collection of our Headline class object for the UI to handle and display.

Headline Class Model

The Headline class is the object that will be loaded and a collection of these will be built and returned from the data service method.  Create a new folder in the Mvvm.PCL project called "Model" and add a new file called Headline.cs.


    public class Headline
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string Url { get; set; }
        public DateTime Published { get; set; }
    }


IDataService

In good practice, create an interface for the DataService class.  This would allow for taking advantage of dependency injection if you chose to do so. Add a new interface file to the model folder called IDataService.cs.  Here is the interface:


namespace Mvvm.PCL.Model
{
public interface IDataService
{
void GetHeadlines(Action<List<Headline>, Exception> callback);
}
}

The interface defines a single method that accepts a delegate with a collections or List<T> of Headline and an Exception parameter.

DataService

Next, in the same folder, add the DataService.cs file and implement the interface.

    public class DataService : IDataService
    {
        public void GetHeadlines(Action<List<Headline>, Exception> callback)
        {
            throw new NotImplementedException();
        }
    }


HttpWebRequest

Most simple requests for data are done with the WebClient class, however this class is not available in Portable Class libraries and is really only an abstraction of what must be used and that is the HttpWebRequest.

Add a new method to the class called MakeAsyncRequest accepting a url (string) as a parameter and set the method to return a Task<string>. Within the method I'll use the Task.Factory.FromAsync method to call the url asynchronously returning the Task<WebRequest> then use a continuation to read the WebResponse.


        private static Task<string> MakeAsyncRequest(string url)
        {
            HttpWebRequest request = WebRequest.CreateHttp(url);
            request.Method = "GET";

            Task<WebResponse> task = Task.Factory.FromAsync(
                request.BeginGetResponse,
                (asyncResult) => request.EndGetResponse(asyncResult),
                (object)null);

            return task.ContinueWith(t => ReadStreamFromResponse(t.Result));
        }

        private static string ReadStreamFromResponse(WebResponse response)
        {
            using (Stream responseStream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(responseStream))
            {
                string strContent = sr.ReadToEnd();
                return strContent;
            }
        }

The GetHeadlines method can now be completed. First add the static url.

 private readonly string uri = "http://blogs.windows.com/windows_phone/b/wpdev/rss.aspx";


Then declare a variable to hold the results of the MakeAsyncRequest method and set the call with the await keyword so the UI thread is not blocked.

var t = await MakeAsyncRequest(uri);

You will also have to mark the method as async or the compiler will give you an error telling you to do so.


public async void GetHeadlines(Action<List<Headline>, Exception> callback)
{
...
}

The results returned are a string type and there are a couple of options to get it into a nice format to work with.  Your first option might be to use the Silverlight SyndicationFeed class which is in the System.ServiceModel.Syndication namespace. However, it is not inherently available in the portable classes and you'll need to go searching for it on your dev machine. Hint (C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ServiceModel.Syndication.dll).

I'm choosing to use LINQ and doing Linq to XML here to get what I need out of the results string and inflate my classes and return it.

Here is the completed method.


        public async void GetHeadlines(Action<List<Headline>, Exception> callback)
        {
            // locally scoped exception var
            Exception err = null;
            List<Headline> results = null;
            try
            {
                var t = await MakeAsyncRequest(uri);
                StringReader stringReader = new StringReader(t);
                using (var xmlReader = System.Xml.XmlReader.Create(stringReader))
                {
                    var doc = System.Xml.Linq.XDocument.Load(xmlReader);
                    results = (from e in doc.Element("rss").Element("channel").Elements("item")
                               select
                                   new Headline()
                                   {
                                       Title = e.Element("title").Value,
                                       Description = e.Element("description").Value,
                                       Published = Convert.ToDateTime(e.Element("pubDate").Value),
                                       Url = e.Element("link").Value
                                   }).ToList();
                }
            }
            catch (Exception ex)
            {
                // should do some other
                // logging here. for now pass off
                // exception to callback on UI
                err = ex;
            }
            callback(results, err);
        }


That covers all of the code needed in the Portable Class(es) for getting the data, just need to edit the MainViewModel class constructor to create the DataService class, implement the new method and create a Headlines property.

MainViewModel
Add a new property for the headlines to be bound to by the UI.


        private List<Model.Headline> _headlines;
        public List<Model.Headline> Headlines
        {
            get { return _headlines; }
            set
            {
                _headlines = value;
                RaisePropertyChanged(() => Headlines);
            }
        }

In the constructor, create an instance of the DataService and execute the method.  I did mention earlier that there is an IDataService for DI, but for this example an concrete DataService class is created.


        public MainViewModel()
        {
            /// create a new dataservice class
            var service = new DataService();
       
            /// call getHeadlines passing headlines and exception delegate vars
            service.GetHeadlines((headlines, err) => {
                if (err != null)
                {
                    /// if there is an error should create a property and bind to it for better practices
                    System.Diagnostics.Debug.WriteLine(err.ToString());
                }
                else
                {
                    /// set the property
                    this.Headlines = headlines;
                }
            });
        }



Adding the UI Elements

Windows Phone

Open the MainPage.xaml page and wrap the previous TextBlock from part 1 in a StackPanel then add a ListBox.  Set the ItemsSource property of the ListBox to {Binding Headlines, Mode=TwoWay}, then add a simple template with a TextBlock to show the title of the story.


        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
            <TextBlock Text="{Binding Hello, Mode=TwoWay}" Foreground="White" FontSize="18" />
            <ListBox ItemsSource="{Binding Headlines, Mode=TwoWay}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <ListBoxItem>
                                <TextBlock Text="{Binding Title}" />
                            </ListBoxItem>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                     
            </ListBox>
            </StackPanel>
        </Grid>

Windows Store

The store app is just as easy.  In MainPage.xaml, add a GridView controls, set the ItemsSource to {Binding Headlines, Mode=TwoWay}, but in this case I'll define an ItemTemplate outside of the control called PCLItemTemplate and display the Title and the Description.


        <GridView ItemsSource="{Binding Headlines, Mode=TwoWay}" Grid.Row="1" ItemTemplate="{StaticResource PCLItemTemplate}" />
     

    <Page.Resources>
        <DataTemplate x:Key="PCLItemTemplate">
            <StackPanel Orientation="Vertical" Width="500" Height="250">
                <TextBlock Foreground="White" Text="{Binding Title}" FontSize="18" HorizontalAlignment="Center" Margin="20,10,20,0" TextTrimming="WordEllipsis"/>
                <TextBlock Foreground="White" Text="{Binding Description}" Style="{StaticResource ItemTextStyle}" HorizontalAlignment="Center" Margin="20,10" TextTrimming="WordEllipsis"/>
            </StackPanel>
        </DataTemplate>
    </Page.Resources>


Summary

 Running either apps presents the data in a different context and there is complete control as to the presentation and design choices based on the platform.  If you are looking to create Windows Store apps and/or Windows Phone applications  Portable Class Libraries is a great way to leverage code within your multiple platform target solution.  MvvmLight is a choice of mine and many others and fits very well too thanks to others in the community.



Full source code available here: http://sdrv.ms/WpBGqS
Read more →

Thursday, January 24, 2013

Portable MVVM Light - Move Your View Models

,

Portable Class Libraries 

Portable Class Libraries were added as a project type in the interest of creating an assembly that you could use across the .NET Framework, Silverlight, Windows Phone 7, or Xbox 360 platforms without modifications.  Well, not really that easy.  There is some work to do and as you get into the development of PCLs you'll find out that there is really a sliver of what you'd hope is supported. (http://msdn.microsoft.com/en-us/library/vstudio/gg597391(v=vs.110).aspx)

MVVM Light

Where I have found it for me is in Windows Store and Windows Phone (7.5 and 8) with MVVM Light. I have been using this MVVM framework exclusively for a few years now on Silverlight, WPF, Windows Phone and now Windows Store platforms and each release gets better.

Most recently, another MVVM Light fan, Oren Novotny (@onovotny) ported the MVVM Light project and made it possible to use it in a Portable Class Library. This is great, code reuse is the ultimate time saver. And when developing Windows Store Apps or a Windows Phone App; making a complimentary piece for the other just makes sense when the UI is really the only difference and even that is almost the same.

Example Project

Open Visual Studio 2012 and create a new project.  I like to start with the "Other Project Types" and select the Blank Visual Studio Solution; name it MvvmPortable and click save. Next add a Windows Store App (C# Blank Template) and call it Mvvm.Store. Add a new Windows Phone 8 project to the solution named Mvvm.Phone.

Now add a new project to the solution and select the "Portable Class Library" project type.


Click OK and then you'll be presented with a dialog to choose the platforms to be supported. Select all except XBox and for Windows Phone choose 7.5 or higher. (An error will occur when adding the nuget packages later if the 'Windows Phone 7.1 or higher' option is chosen).


Click OK and now the MVVM Light packages can start to be added via nuget.

Nuget

If you are  not using nuget, please pause here and go to nuget.org and/or install via Tools->Extensions And Updates.

Mvvm.PCL Project
Right click the project and select the Manage Nuget Packages and in the dialog search for "Portable.MvvmLightLibs" and be sure that the Include Pre-release option is on, or you can use the package manager console and use the command install package portable.mvvmlightlibs -prerelease.


Repeat this process for the Windows Phone and Windows Store projects.

Next we need to add the MVVM Light specific platform assemblies to each of the respective platforms and do some setup and cleanup to make this all work.

Right Click the Windows Store project, select Manage Nuget Packages and search for MVVM Light and click the install button. In doing so, a few folders and files will be added to the project and you may see some errors which we'll clean up and repeat the process for the Phone project.


Moving ViewModelLocator,ViewModels and Wiring it Up

Now on to the fun! 

In the Mvvm.PCL project create a folder call ViewModel in the root of the project. Then expand the  ViewModel folder in the Mvvm.Store project and select the ViewModelLocator.cs and MainViewModel.cs file and cut and paste those to the ViewModel folder in the Mvvm.PCL project.

Open each of those and change the namespace to Mvvm.PCL.ViewModel from Mvvm.Store.ViewModel.

Since the ViewModelLocator has moved, the store app needs to know where to find it and the ViewModels, so open the App.xaml file in the Mvvm.Store project and change:

 xmlns:vm="using:Mvvm.Store.ViewModel" 
to

 xmlns:vm="using:Mvvm.PCL.ViewModel" 

and we need to modify the Resources section because the nuget installer for MvvmLight puts in some extra entries for the ViewModelLocator


    <ResourceDictionary>
        <vm:ViewModelLocator p7:Key="Locator" p8:IsDataSource="True"
                        xmlns:p8="http://schemas.microsoft.com/expression/blend/2008"
                        xmlns:p7="http://schemas.microsoft.com/winfx/2006/xaml" />
        <ResourceDictionary.MergedDictionaries>
                <!--
                    Styles that define common aspects of the platform look and feel
                    Required by Visual Studio project and item templates
                 -->
            <ResourceDictionary Source="Common/StandardStyles.xaml" />
        </ResourceDictionary.MergedDictionaries>
   
    </ResourceDictionary>

Finally for the Store app we'll go to the MainPage.xaml and set the DataContext and add a TextBlock to be filled from the MainViewModel.cs in the portable class library that we'll add following that.

In the MainView.xaml page add the DataContext property at the top of the page after the other declarations.


    ...
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{Binding Main, Source={StaticResource Locator}}"
    >
Next in the grid add the TextBlock as follows


    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Foreground="White" FontSize="42" Text="{Binding Hello, Mode=TwoWay}" />
    </Grid>
If you compile the store project at this point you will get some errors concerning MvvmLight confilcts. These occur because there are class duplicates in the portable and in the specific versions of the assemblies.  In order to alleviate the errors, expand the references folder in the project and select the *.Win8 assemblies and delete them.

Adding Hello to MainViewModel
Now that the wiring up of the relocated ViewModelLocator and MainViewModel are completed we can add the simple "Hello" property in the MainViewModel so it can be bound to in the store project.

Open MainViewModel.cs and add the property as follows:


        private string _hello = "Hello";
        public string Hello
        {
            get
            {
                return _hello;
            }
            set
            {
                _hello = value;
                RaisePropertyChanged(() => Hello);
            }
        }

Set the store project as the default project to run and either run in the simulator or on your local machine and you should see "Hello" appear in the top left of the application.


Wiring up the Phone Project

The process here is pretty much the same as was done for the store project.  Instead of moving the ViewModel folder in the phone project; it can be deleted.

Open the App.xaml and make the adjustments to let the application know where the ViewModelLocator and ViewModels are located. Note that making these references in the phone project are different that in the store project, albeit subtle can trip you up.

Change  

 ...xmlns:vm="clr-namespace:Mvvm.Phone.ViewModel" mc:Ignorable="d">

to

 ...xmlns:vm="clr-namespace:Mvvm.PCL.ViewModel;assembly=Mvvm.PCL">

then make the modifications to the Application.Resources portion as follows:

  <Application.Resources>
    <local:LocalizedStrings xmlns:local="clr-namespace:Mvvm.Phone" x:Key="LocalizedStrings" />
        <vm:ViewModelLocator p6:Key="Locator"
                         p7:IsDataSource="True" xmlns:p7="http://schemas.microsoft.com/expression/blend/2008"
                         xmlns:p6="http://schemas.microsoft.com/winfx/2006/xaml" />
    </Application.Resources>

Next, open the MainPage.xaml and add the DataContext declaration and the TextBlock as we did for the store application.


...
shell:SystemTray.IsVisible="True"
    DataContext="{Binding Main, Source={StaticResource Locator}}">

adding the TextBlock

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBlock Text="{Binding Hello, Mode=TwoWay}" Foreground="White" FontSize="18" />
        </Grid>

And finally as mentioned in the store project, you will get the assembly conflicts so be sure to remove the .*WP8 references in the phone project prior to building the solution here.

Run the application and you'll see the Hello presented in the same location on the phone app.


Wrapping Up

All of the other capabilities that you may or may not be familiar with in the MVVM Light framework is still available to you within the specific projects or of you'd like extract those as well too.  I find that the navigation and switching of the views is still best served within the specific platforms.

I have in my projects moved services negotiation for getting data into the PCL assembly using the Microsfoft.BCL.Async library via nuget too and that is also great but a little different depending on your experience with the platform and WebClient versus HttpClient requests.

Enjoy and feel free to ask questions.

Part 2 - Adding a Data Service


Read more →

Tuesday, January 15, 2013

Picking the Right Tools for Your Project

,
Over the weekend I was able to release the first of many Windows 8 applications (Download and Rate here) into the store that I have been working on. This first one is just a RSS type application for DZone.com, but it just the first version and the next installment will add more content.  If you have ever planned a good, cross platform application before you may or may not understand that picking the right tools for job are important, and yes even what you're using for the front end language matters sometimes as it did in my case here.

Here is a run down of the application architecture components:

  • Node.js REST API on Azure
    • Express : MVC type framework for Node.js for routing, rendering, HTTP Listener
    • Memory-Cache : memory caching on server
    • Cheerio : JQuery on the server, lightweight simple HTML parsing
    • Async : parallel library for Node.js 
  • Windows 8
    • HTML5/WinJS
TypeScript was also used in the Node.js project as well to build out some of the model objects.

I wanted my app to present more. More than just the headline and a link off to another web browser as well as offer the ability to re-use what I had done for Windows Phone or other mobile devices. 


API Architecture Choices - Reuse is Key

The RSS feeds don't change that much, so I want to create a way to have an API I could reuse for other platforms, but also leverage some caching for high availability, scale out if necessary and also make the development as fast as possible. I chose to go with Node.js on Azure to solve this challenge.

Node.js (http://en.wikipedia.org/wiki/Node.js) - Node.js is a packaged compilation of Google's V8 JavaScript engine, the libUV platform abstraction layer, and a core library, which is itself primarily written in JavaScript. Node.js was created by Ryan Dahl starting in 2009, and its growth is sponsored by Joyent, his employer.

Node also has Node Package Manager (npm) which I would or most would say is the equivelant to .NET's nuget package library repository for getting community contributed libraries for accomplishing common tasks such as caching, async and so forth.

I hadn't used node before but I have plenty of JavaScript experience and it was on my list of "want to learn" this year.  I was recently asked why node instead of Web API, other just to say "I used node.js"?  Good question, and a legit one too.  So here is the answer;

Web API is great, I love it and give a talk on "Why you should be using it" at code camps quite often.  However, I found that using C# to parse HTML to not be as flexible and lacked performance in comparison to using Cheerio (JQuery on node.js) when outside of the standard RSS or ATOM formatted feeds. JavaScript is really great at parsing strings.  Secondly, the ability for me to make routes in Express was really easy in comparison to ASP.NET.  For example, in ASP.NET if I wanted to setup a route to handle a controller / action / id route; there are changes needed in the routing configuration as well as potential changes in the controller too.

Routing Config


routes.MapHttpRoute(
    name: "myNewRouteAction",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

Controller Code


public class ProductsController : ApiController
{  
     [HttpGet]  
     public string Details(int id)  { ... }
}

Or

public class ProductsController : ApiController
{  
     public string GetDetails(int id) { ... }
}


This sets up the API for the action name to be in the url like http://localhost/api/products/details/1. By contrast in node the same is accomplished with Express.js by doing the following


app.get('/api/products/details/:id', function(request, response) { ... });


Next, in node I can take advantage of running multiple processes at once for checking for updates while also hosting a REST API for the application.  In another application there are two worker roles in Azure, basically Windows Services, doing this type of work and a single Web role for my Web API.  This allows for me to consolidate the processes into one right now and if the need arises I can break the back end architecture into multiple processes. Flexibility and some simplicity I like here. Here is an example where 3 processes are running at once doing tasks at different intervals all non-blocking.

app.js 

var job = function() {
     console.log("working at 1 second.");
 };
var job2 = function() {
     console.log("working at 3 seconds.");
};
setInterval(job, 1000);
setInterval(job2, 3000);

Ouput in Console




Finally, I chose JavaScript/HTML for the UI portions which I'll cover more reasons why later and it's nice to code JavaScript everywhere.

C#/XAML or HTML5/JavaScript/CSS3 ?

Now I will mention that C# is my first language of choice when diving into any new project and in fact that is what I initially started with, but I found that when getting the contents of the RSS feeds, which were non-standard formatted and in order to consume RSS nicely in C# or VB.NET you have a dependency on the SyndicationFeed assembly which is good and bad. Good if the feed is formatted in the standard RSS or ATOM formats, but bad if the provider has extended it.

Once more the article content was also available in nice print formatted HTML, however when using C# in Windows 8 you must embed a browser control and the flow is not fluid in landscape mode.  At least, not the way it should intuitively should appear. However in JavaScript you can take the HTML from the print view and set the innerHTML equal to the result and sprinkle some CSS in there and you are set. No fuss. So HTML5 is the choice here.

In making the decision there are some features that I really enjoy about the language and the ability to create Windows applications versus XAML.

There is a clear separation of concerns between what is Presentation, Styling, and Logic that I think I had taken for granted in my web development projects.  When using C# and XAML I really structure my project with MVVM pattern using MVVM Light, use some naming convention on my files and folder structures to ensure that just by looking at the project I know what does what where.

In a JavaScript Windows 8 project it's clear, just in the tooling and file types.  Now make no mistake you can embed all of the CSS and JavaScript right in the HTML and spaghetti it all up just like anything.  However, the templates and the maturity of the tool set and language almost keeps you from doing so.

The HTML5 support in Blend is also great, especially when seeing what CSS styles are applied to what HTML elements, and using the tooling to create a new style from an existing style.  I encourage you to view the video on blendinsider.com .

Some other items I'll quickly mention that I like about JavaScript projects in Windows 8

  • CSS
    • multiple background layers and overall styling much easier than XAML
    • Supporting snapping, full, landscape etc through media queries I found much more intuitive
  • JQuery Support
    • Who doesn't like JQuery when it comes to getting to the DOM?
  • Web Essentials! not that this has anything specific to do with WIndows 8, but if you are doing any HTML, CSS, and/or JavaScript development you MUST get this.  I have been using this for a while and it continues to get better and now has its own dedicated site as http://vswebessentials.com/
I will still use C# and XAML as it is my first set of tools, but don't forget the others in the box.  There have been some fantastic tools thrown at the developers and some are very quick to poo poo the idea of a new coding language or application of an existing language in a different way.  Pick what best works towards the success of the project.

Here are a few resources for HTML5 and JavaScript Development for Windows 8 




Read more →
Powered by Blogger.
 
Creative Commons License
TattooCoder.com by Shayne Boyer is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.