tag:blogger.com,1999:blog-43159281318873733642024-03-05T10:55:32.610-08:00ProQJust me and my mumblings on everyday issues.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.comBlogger58125tag:blogger.com,1999:blog-4315928131887373364.post-15263592672901767532014-06-29T11:04:00.003-07:002014-06-29T11:24:45.401-07:00OWIN and Katana, a first lookSince I do quite a lot of web development, I thought it a good idea to take a first look at <a href="http://owin.org/">OWIN </a>and <a href="https://katanaproject.codeplex.com/">Katana</a>, get a feel of what they both are about and how they can be used in a project. They are both part of a new web hosting model, where OWIN is the specification of this model and Katana is an actual implementation of this specification. In this post I will give you an overview of both and show you how you can build the basis for a web application using the Katana project.<br />
<br />
But, let me first give you a small intro on both.<br />
<br />
In .NET, when you build a web application, what you typically do, is use ASP .NET (either webforms or MVC) and host your application in IIS. This framework has been around for quite some time, and it has really become big. For some applications, this model can be bloated, since it runs a lot of things you don't really need in your application.<br />
<br />
What they wanted to aim for at Microsoft with OWIN and Katana, is build a basis for a framework, that is really light weight, with just the essential things for a web application in it. And if you need extra's you just pull them in as you need them. More or less similar to what you would do to a nodejs server application. Very light weight, but also very powerful.<br />
<br />
Along came OWIN, which is a specification for how you can build a web server that can host .NET code. It sits between a hosting environment, which in this case can be either IIS or something else, like a Windows Service, or a simple Console Application, and your actual application code. Any additional middleware, like authentication, can use the OWIN abstraction to be plugged into your application.<br />
<br />
So, what does OWIN actually define or specify? Well, the most important part of the OWIN specification is the application delegate, which looks like this:<br />
<br />
<pre style="font-family: 'Courier New'; font-size: 10pt; margin: 0in 0in 0.0001pt;">using AppFunc = Func<</pre>
<pre style="font-family: 'Courier New'; font-size: 10pt; margin: 0in 0in 0.0001pt;"> IDictionary<string object="">, // Environment</string></pre>
<pre style="font-family: 'Courier New'; font-size: 10pt; margin: 0in 0in 0.0001pt;"> Task>; // Done</pre>
<br />
The application delegate has an argument of type IDictionary<string object="">, which is called the environment dictionary. This dictionary contains information about one single request, its response and any relevant server state. In it, you will be able to find keys like owin.RequestMethod, which can have a value like GET or POST, or owin.RequestPath, which contains the value of the actual called URI. An overview of possible values can be found in the <a href="http://owin.org/spec/owin-1.0.0.html">OWIN specification document</a>. </string><br />
<br />
The second argument of the application delegate, the actual return type, is a Task, that will be returned once it has finished processing. You will see the usage of this Task once I start building up some more practical examples. What you will notice, with this task, is that the OWIN architecture is asynchronous by design.<br />
<br />
The application delegate is a way of hooking into an OWIN server. Meaning that if you want to hook into an OWIN environment, you will need to have a method that complies to the signature of this application delegate.<br />
<br />
Now, where OWIN is a specification, Katana is Microsoft's implementation of this specification. In Katana you can find a couple of OWIN hosts either for IIS, or for self-hosting. You will also find a couple of classes that help you with talking to OWIN, so you don't need to, for instance, take values directly from the environment dictionary. And you will also be able to find a couple of middleware components, like authentication, ...<br />
<br />
So, let's build a small application with Katana. For this we start of with an empty console application, which we will use as a host for our application. In this we will install the OWIN self host nuget package.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihA_qM5zD9NBWRy-pR-yun0fsk0fqbLJgFVvGxZkp083oPzam_ypsKkRJ2Qm5yiz-6AiQhvUtPl_4TMwpfQ6aZQ9n8eC6p_u_yV-44BQGqRqFL_vFtaKl3tKk43cV5K1cAlp0cjWItlyA/s1600/self+host.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihA_qM5zD9NBWRy-pR-yun0fsk0fqbLJgFVvGxZkp083oPzam_ypsKkRJ2Qm5yiz-6AiQhvUtPl_4TMwpfQ6aZQ9n8eC6p_u_yV-44BQGqRqFL_vFtaKl3tKk43cV5K1cAlp0cjWItlyA/s1600/self+host.png" height="267" width="400" /></a></div>
<br />
Once we have this, we can start hosting an application. For this we use the WebApp class which represents the self hosting OWIN server and tell it which url it should listen on. We also give it a configuration.<br />
<br />
The configuration class is based on convention, it needs a Configuration method that takes an IAppBuilder as an argument.<br />
<br />
<br />
<script src="https://gist.github.com/vermegi/d02369af364706978b2b.js"></script>
<br />
Now we can start configuring our OWIN host. First thing we will do is a very simple host, which prints out some information of the response that came in, and which returns a string that says Hello OWIN and Katana. For this we use the Run method on the IAppBuilder. This will get a context, which gives us access to the environment variable.<br />
<br />
<script src="https://gist.github.com/vermegi/6e68c60e80f7cba4f15e.js"></script>
As you can see in the code example, the interface is async by default. The Request and Response properties give us easy access to the data in the environment variable.<br />
<br />
When we run this example, we can go to the localhost:4321 uri. It will give us the following response:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmGtzX0l6ZUMb98sRcHiFO8sbNeZRPrxREfEYi1OV4DsmyrFHwX8dxyHBPv6aamNy2QU7_KxneLzGprFG_PRqJswielyP93NUOYuM1pJaLYDvDaagpJ87OYehuR3xYVbhMx0b3SbH4N30/s1600/firstpage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmGtzX0l6ZUMb98sRcHiFO8sbNeZRPrxREfEYi1OV4DsmyrFHwX8dxyHBPv6aamNy2QU7_KxneLzGprFG_PRqJswielyP93NUOYuM1pJaLYDvDaagpJ87OYehuR3xYVbhMx0b3SbH4N30/s1600/firstpage.png" height="152" width="320" /></a></div>
<br />
And in our Console, we can see the method and URI printed out:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWBjvISMdNGOEM2SSxRIO-X47EDimA09ELoQeVYkgo2a9mcReV0tvo5YGnstH0zIXsFrt_0KfBARZcqSpBe5NXuAh68G00sFKNT558GZXdJaX44iK1r8eGsIkBwGprd20bRr2XXDcuFxU/s1600/console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWBjvISMdNGOEM2SSxRIO-X47EDimA09ELoQeVYkgo2a9mcReV0tvo5YGnstH0zIXsFrt_0KfBARZcqSpBe5NXuAh68G00sFKNT558GZXdJaX44iK1r8eGsIkBwGprd20bRr2XXDcuFxU/s1600/console.png" height="209" width="320" /></a></div>
<br />
So, that's a really simple example. We can also add some preprocessing or postprocessing to our request. For this you utilize app.Use. This will take 2 arguments, the context, but also a reference to the next middleware delegate in the chain. Whatever you want to do as preprocessing you put before your call to the next delegate. Whatever you want as postprocessing, you put after the call to the next delegate.<br />
<br />
<script src="https://gist.github.com/vermegi/70d21f73a1574f2ede5f.js"></script>
This gives us the following output:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd_lKACRAIuFu4nnDBHF5sSR2aBBSbh5rdeeRADprl8QVnQOoDHW4JmPflQTimlhyphenhyphenF3mC6Ds9wyU5NQqi0SoulhjLe8U-hKIr6J__ovUnc0m7hyphenhyphenRfwddMFY0_yuG_A5LdBeyhJO6-X8kI/s1600/preprocessing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd_lKACRAIuFu4nnDBHF5sSR2aBBSbh5rdeeRADprl8QVnQOoDHW4JmPflQTimlhyphenhyphenF3mC6Ds9wyU5NQqi0SoulhjLe8U-hKIr6J__ovUnc0m7hyphenhyphenRfwddMFY0_yuG_A5LdBeyhJO6-X8kI/s1600/preprocessing.png" height="209" width="320" /></a></div>
<br />
Another way of programming this, is with separate classes instead off with delegates. The same example than looks like this:<br />
<br />
<script src="https://gist.github.com/vermegi/ab0bdf00bc23187640f0.js"></script>
<br />
You create a class with an Invoke method. This method will get the environment dictionary directly. If you want to use the OwinContext instead, you can new it up. Your next delegate this time will not be passed as an argument to the Invoke function, but will be passed as a constructor argument.<br />
<br />
With all this you can already do some nice stuff. Beware though, since the API will still be subject to changes. For people wanting to try this on non Windows machines, there's also a Nowin nuget package, that also runs on Mono. Hope this entises you to try some of this stuff out.<br />
<br />
<br />Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-39102159046869208232014-02-09T01:58:00.001-08:002014-02-09T01:58:51.415-08:00Extending Durandal<h4>
Summary: combining Durandal and ASP .Net MVC, getting the best of both worlds</h4>
<div>
<br /></div>
Experience has taught me that, when doing web projects, JavaScript is one of the technologies you will have to learn to live with. It will always be present and it will always bug you (literally). And in each project, you will have devs at your disposal who are better, or worse at writing JavaScript code. It's just a fact that, once you start writing a whole bunch of JavaScript, it can get quite messy, very quickly. <div>
<br /></div>
<div>
In my recent project setup, I wanted to be able to avoid such a mess, by providing well structured JavaScript code from the beginning. But, without having to sacrifice the comfortable environment the ASP .Net MVC framework gives to my devs.<br /><div>
<br /></div>
<div>
For this, I looked into a couple of JavaScript frameworks. Without treading into details here, the framework that suited my situation best was <a href="http://durandaljs.com/">Durandal</a>. It's not that hard to learn, it makes extensive use of <a href="http://requirejs.org/">RequireJS</a> (which was already known by a lot of my developers) and it uses <a href="http://knockoutjs.com/index.html">knockout</a> for its bindings, which, for people coming from for instance XAML, looks quite familiar. </div>
<div>
<br /></div>
</div>
<div>
For people unfamiliar to Durandal, knockout or RequireJS, you can find very good info for getting started with all three of them. </div>
<div>
<br /></div>
<div>
Now, the problem with my recent project, was the combination of the good parts of ASP .Net MVC and the good parts of Durandal. For instance, what I like about ASP .Net MVC is the fact I can use statically typed helpers in my HTML. They help my devs a lot at being consistent and at keeping the error rate low(er). Kinda like what <a href="http://stackoverflow.com/questions/14981833/how-can-i-use-cshtml-files-with-durandal">this stackoverflow question</a> poses. So I started thinking of an easy way to accomplish this. </div>
<div>
<br /></div>
<div>
My application itself will consist of little mini-SPA's. Meaning that for each part of the application, for instance the detail of a customer, or the overview of payments, ... we will make a Single Page Application (SPA). The starting point of each of these little mini-SPA's will be a .cshtml view which will get returned by an action on a controller. This .cshtml view will contain a div for the applicationHost (this is standard Durandal) and some code to start up an SPA on this page. </div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/vermegi/8896718.js"></script></div>
<div>
<br /></div>
<div>
As you can see, this is standard Durandal code. The only thing I did was make my own little module that sets up an SPA for a certain viewmodel, so you don't have to repeat that code over and over again in the application.</div>
<div>
<br /></div>
<div>
Now, what durandal does once you set up an SPA for barcode/shell, is that it starts looking for barcode/shell.js (your viewmodel) and barcode/shell.html (your view) and it links these two together. But the thing is, I actually want to set up a view in which I can use the MVC helpers. That's not possible in an HTML file. </div>
<div>
<br /></div>
<div>
So, I started digging in the Durandal source code, looking for the part where the viewmodel and the view get linked together. Its in Durandals viewLocator.js file. In here, I added some extra script, giving you the ability to add an extra div (I called it applicationContent, out of convenience) in your original .cshtml file (lines 15 through 18). </div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/vermegi/8896807.js"></script></div>
<div>
<br /></div>
<div>
Once you start up you SPA Durandal will now look for the presence of this div and if it can find one, it will put its contents in the applicationHost div. You can now use this abbility in your .cshtml file:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/vermegi/8896820.js"></script></div>
<div>
<br /></div>
<div>
As you can see I can now use things like Html.BeginForm or our Translations resource in the cshtml file. It's all placed in a div called applicationContent. Once my SPA starts up, it will place this content in the applicationHost. You also have the ability to use knockout bindings inside your applicationContent. You can see I did this for the submit binding on the form and for the pdf_url in the iframe. </div>
<div>
<br /></div>
<div>
If you want to look at this extension of Durandal:<a href="https://github.com/vermegi/Durandal"> I forked the project with my little addition</a>.</div>
<div>
<br /></div>
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-63435442650211226642014-01-25T02:22:00.001-08:002014-01-25T02:22:57.173-08:00Building a cross platform solution for Windows Phone and Windows 8. Part VI: Behaviors for coping with orientation changesPrevious parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_23.html">Part V: Event to command</a><br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<br />
In the last post we looked at an EventToCommand implementation to easily databind our events to commands, even when we don't have a Command property on a control.<br />
<br />
In this post, I will run you through another trick, to ease the development of your views.<br />
<br />
One of the behaviors you will probably want in your application is the ability to react to orientation changes. You can easily do this by creating an event handler for the OrientationChanged event in the code behind of your page. You will have to do this in every page you want to be able to react to orientation changes. Resulting in copies of the same piece of code all over the place.<br />
<br />
But there is actually a more elegant way of dealing with this, and it is based on behaviors. What you can do is write a specific behavior that does nothing more than attach an event handler to the OrientationChanged event of the associated page. Based on the name of the new orientation, you can now load a specific state of you VisualStateManager.<br />
<br />
<script src="https://gist.github.com/vermegi/8614361.js"></script>
<br />
Of course, in XAML, you now have to create the necessary VisualStateGroups for the specific orientations.<br />
<br />
<script src="https://gist.github.com/vermegi/8614370.js"></script>
<br />
The only thing missing still is a small extra piece of XAML to make use of the OrientationChangedBehavior.<br />
<br />
<script src="https://gist.github.com/vermegi/8614377.js"></script>
<br />
That's it, small and simple little trick. In the next part we'll look at the troubles you can have when your application needs to be tombstoned.<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_23.html">Part V: Event to command</a><br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: TombstoningGitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-58388735521563116422013-12-23T05:48:00.002-08:002013-12-23T05:48:20.190-08:00Building a cross platform solution for Windows Phone and Windows 8. Part V: Binding events to commandsIn the previous part of this series, we did quite a lot. We mocked out any application differences in our ViewModels, we introduced dependency injection and we created base classes for our platform specific pages.<br />
<br />
This part will be less complicated, but will again contain a very necessary part if you want to end up with a reusable framework for your Windows Phone and Windows 8 applications. Up until now we have created Views that we can databind to our ViewModels. For this our ViewModels contain either data properties or command properties. It is with this last kind of properties you might have some issues in databinding scenarios. And this doesn't only go for cross platform applications, you will have this issue every time you want to take the MVVM approach.<br />
<br />
The thing with command properties is that, out of the box, they are only databindable to, well, Commands. So, a button for instance, poses no problem, since it has a Command property. But what if, for instance, you wish to trigger a command based on a Tap event. This will not be possible by default. But, you can provide some extra pipe-lining to make this possible nonetheless.<br />
<br />
What we'll do to get around this, is write our own TriggerAction. A TriggerAction describes an action to perform by a trigger. The good thing is that you can attach a TriggerAction to an EventTrigger. An EventTrigger will then execute your TriggerAction based on a certain event.<br />
<br />
To get all this working, first thing you will have to do is add a reference to the Systems.Windows.Interactivity namespace. On Windows Phone you can find this reference under Assembly - Extensions (I had to look for it too). For Windows 8 you will not find this assembly in your references, but you can use <a href="https://www.nuget.org/packages/Windows.UI.Interactivity">this</a> nuget package.<br />
<br />
Once you've done this, you will find you can add an EventTrigger for any event you would like. In the following example I have added one for the Tap event on a Border control.<br />
<br />
<script src="https://gist.github.com/vermegi/8007182.js"></script><br />
<br />
Next step, now that we have our EventTrigger, is write a TriggerAction that translates our event to a command. This is actually not that hard. You notice in the code sample above I use a framework:EventToCommand type, which I provided myself. This is my TriggerAction which has one property, Command. It looks like this.<br />
<br />
<script src="https://gist.github.com/vermegi/8007201.js"></script><br />
<br />
This class inherits from a TriggerAction for a FrameworkElement (this is just the base class for all possible controls). The first line registers my Command property as a DependencyProperty. This is needed so you can assign values to this property from within your XAML. That is also why, in the actual property, you see the use of GetValue and SetValue - that is just because we are using a DependencyProperty.<br />
<br />
The Invoke method in my EventToCommand is more important. It gets executed each time the associated event gets fired. What it does is, it looks wether the Command can be executed and when it does, it executes the Command.<br />
<br />
With this, you can more or less databind anything in your views. More or less, because if you want to databind your application bar in a Windows Phone application, you will have to go through some extra effort, which involves a lot more code. You can get a pointer to what needs to be done <a href="http://bindableapplicationb.codeplex.com/">here</a>.<br />
<br />
Next part, I will show you another little trick to easily react to orientation changes.<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-17292129439093254032013-12-15T08:39:00.004-08:002013-12-17T06:16:07.919-08:00Building a cross platform solution for Windows Phone and Windows 8. Part IV: Mocking out the differencesOther parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<br />
In the previous part I talked about the MVVM pattern as a great way to share logic in your application. Your ViewModel (and Model) code can be placed in a portable class library, thus making it reusable. But, since it is not possible to put any platform specific code in your PCL, you cannot directly use platform specific services from within a ViewModel (this would make your PCL unsharable between platforms). This poses some challenges, but these can quite easily be overcome. This part in our series will be the most extensive thus far, and will contain the most advanced concepts, like inversion of control, dependency injection, and reflection. But bear with me, it will all be worth it in the end!<br />
<br />
Let's first look at one of these platform specific behaviors: Windows Phone and Windows 8 both allow you to navigate from one page to another. The way they do this, however, is different between the two platforms. They both have a Navigate method for this, but the method exists on two different types, and also, the actual parameterlist of this method is different on each platform. You will need to find a solution to get a comparable way of navigating between pages on both platforms. You can do this by wrapping the platform specific functionality with an interface. Your ViewModels can then talk to this interface instead of talking directly to the actual navigation service of each platform.<br />
<br />
I have for instance a MainViewModel which acts as start page for my application. From this MainViewModel you can navigate to other pages in the application. For this, the MainViewModel gets a reference to a INavigate interface through its constructor (this is my own INavigate interface, and not the one you can find in the Windows Store or Windows Phone API). Since I will be navigating in my ViewModels and not in my Views, I decided that when I navigate to another page, this is actually the same as navigating to another ViewModel. Also, I want to be able, when I navigate, to send along an additional parameter, which contains extra data for the ViewModel I navigate to.<br />
<br />
<script src="https://gist.github.com/vermegi/7974904.js"></script><br />
<br />
In the above code you can see it is quite easy to navigate to another ViewModel, and send along extra data (navigate to the SudokuBoardViewModel with a specific game level). But you can also choose not to use this extra data (navigate to the SudokuRulesViewModel).<br />
<br />
The interface itself has one extra method for navigating back.<br />
<br />
<script src="https://gist.github.com/vermegi/7974916.js"></script><br />
<br />
What you will still have to do now is write platform specific implementations of the INavigate service for each platform you want to support. The good thing is, you will need to write this kind of implementations only once. After your first app, you can reuse this effort to a next application (and I will also make sure my own little API will become available on github in the next couple of weeks).<br />
<br />
<br />
<h3>
1. Navigating in a Windows Store application</h3>
<br />
Let's first look at the WindowsStoreNavigator, since this is the easiest to understand. To navigate from one page to the next, you need to make use of your Window.Current.Content property (or rootframe). In a clean Windows Store project you get a reference to this in your OnLaunched event (I set up the entire framework from the OnLaunched handler in the app.xaml.cs file). Next, we will also need some means of associating the ViewModel we wish to navigate to, with a certain View, since navigating in Windows Store applications is done to views and not to viewmodels. For this I will utilize a viewlocator (IKnowWhereYourViewIs). This viewlocator is nothing more than a dictionary that associates views to viewmodels. This way I don't need to code the binding between view and viewmodel directly in the view or in the viewmodel.<br />
<br />
<script src="https://gist.github.com/vermegi/7974933.js"></script><br />
<br />
As you can see, I ask the viewlocator for the view that is associated with the viewmodel I wish to navigate to. Next I tell the rootframe to actually navigate to this view. The second parameter in the second line of the NavigateTo method instantiates my viewmodel. The inversion of control container has been set up with a list of all my viewmodels. For this I utilized TinyIoc, but you can use any wich IoC you like. The main advantage using and IoC container will be that any dependencies your viewmodel uses, will get injected by the IoC, as long as you registered them at startup.<br />
<br />
Navigating with the extra data is a bit more complex. I created a IHandle interface which indicates wether a ViewModel can handle a certain message. If it does, it implements the IHandle<requesttype> interface. Before navigating to the view, I first let the ViewModel handle the actual request.</requesttype><br />
<br />
<script src="https://gist.github.com/vermegi/7974957.js"></script><br />
<br />
One more thing missing after navigating to a certain view, is the actual databinding between View and ViewModel. For this I created an extra base class for each View. In the OnNavigatedTo handler, we will bind the NavigationEventArgs, which in our case is our ViewModel, to the Views' DataContext.<br />
<br />
<script src="https://gist.github.com/vermegi/7974966.js"></script><br />
<br />
And that's it. This allows us to navigate from one ViewModel to another, while sending along data. Also aer we now able to actually databind our ViewModel to the actual View.<br />
<br />
<br />
<h3>
2. Navigating in a Windows Phone application</h3>
<br />
Now that we can navigate in a Windows Store application, let's do the same thing for Windows Phone. As you will see, the API for navigating in Windows Phone is different from the one Windows Store applications use. In Windows Phone you navigate based on a Uri. Also, we will not be able to send along our ViewModel and request as easily. In this case, we will serialize everything before we navigate. Ie. we will serialize our ViewModel type, the actual request and the request type.<br />
<br />
<script src="https://gist.github.com/vermegi/7974981.js"></script><br />
<br />
Again, we will use a MvvmPage base class, which all our views can inherit from. In its NavigatedTo event handler we will now have to (re)create our ViewModel and request. I pulled out this code to another class which implements ICreateViewModels. Since views cannot use dependency injection, I wrapped the IoC in a singleton, which can give me my viewmodelcreator.<br />
<br />
<script src="https://gist.github.com/vermegi/7975006.js"></script><br />
<br />
The ViewModelCreator then uses a deserializer and some reflection to recreate the viewmodel and to make it handle the actual request.<br />
<br />
<script src="https://gist.github.com/vermegi/7975020.js"></script><br />
<br />
The above code is actually the most complex part of the entire framework. An, as said, code like this, you will only have to provide once, after that your can reuse it for your next applications.<br />
<br />
Once you got thi plumbing in place, you can navigate between ViewModels in a way that is reusable on Windows Store and Windows Phone applications. It wil make it easier to put your logic code in a shared library and to easily make changes to it that will get reflected on each platform.<br />
<br />
Hang on for the next part, where I will talk about some extra helper classes to make MVVM work better for you.<br />
<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com1tag:blogger.com,1999:blog-4315928131887373364.post-82846917997996615052013-12-08T01:27:00.000-08:002013-12-17T06:15:43.942-08:00Building a cross platform solution for Windows Phone and Windows 8. Part III: We need a pattern.Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<br />
In the previous part I talked about portable class libraries and mentioned the need for a pattern in our code. This pattern will be the Model - View - ViewModel pattern, or MVVM for short. It divides the pieces of your application in more sensible parts and allows you to better define the responsibilities of each individual part. The View for instance will be responsible for nothing more than UI related code. This will be your XAML file. When using MVVM, I try to define my entire user interface in the XAML of my application. I hardly ever put anything in the code behind (except maybe for some UI specific code), all application logic will go someplace else.<br />
<br />
The Model in this pattern can be either data you need or services you will be using. These will contain quite some logic and we can write them in such a way that they are unit testable.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbcAUwdyt3B6c_Z415B_l9xLR0kgkmnW8KCJRIe9vRlu__1njlvLNyhtBkB878CQsW7KB5bF_BeTiCK6mzgttSMks_05d2_rKglyqV6Z5TBIZKC_x1FGrrv5mYTH_Rk8TJZBQaF_XaV5A/s1600/MVVM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbcAUwdyt3B6c_Z415B_l9xLR0kgkmnW8KCJRIe9vRlu__1njlvLNyhtBkB878CQsW7KB5bF_BeTiCK6mzgttSMks_05d2_rKglyqV6Z5TBIZKC_x1FGrrv5mYTH_Rk8TJZBQaF_XaV5A/s400/MVVM.png" width="400" /></a></div>
<br />
<br />
The ViewModel will sit between the View and the Model and its responsibility will be to shape the data of the Model in a way that is specific for a certain View. As with the Model, it will also be unit testable.<br />
<br />
The ViewModel will contain all the properties for the View to databind to. For these properties you can choose to fire the PropertyChanged event - and thus your ViewModel will implement INotifyPropertyChanged.<br />
<br />
<script src="https://gist.github.com/vermegi/7854898.js"></script><br />
<br />
The above piece of code shows two properties of one of my viewmodels. The first one is for a collection of items. The second one is for a simple property. Both properties fire the PropertyChanged event. As you can see this is done through a lambda expression. I prefer putting this kind of PropertyChanged event wrapping in a base class for my viewmodels and providing the easier lambda syntax. This provides me with compile time checking (and less runtime errors when I make typos). The way to do this, is shown in the following code example.<br />
<br />
<script src="https://gist.github.com/vermegi/7854988.js"></script><br />
<br />
<br />
Next to simple data properties, your ViewModel can also contain command properties. The View can also databind to these (for instance from the Command property of a Button). A command property will ascertain something gets executed in the ViewModel or in the Model.<br />
<br />
<insert code="" command="" here:="" property="" snippet=""></insert><script src="https://gist.github.com/vermegi/7855007.js"></script><br />
<br />
As you can see, I use a RelayCommand class, which again makes the creation of command properties easier. The RelayCommand class will implement the ICommand interface and will provide an API by which you can createICommands based on lambdas or delegates. The RelayCommand class looks like this:<br />
<br />
<script src="https://gist.github.com/vermegi/7855035.js"></script><br />
<br />
When creating commands for your view to databind to, you can also use the CanExecute property, to indicate when a command can be fired, and thus, when the button you databind do should be enabled. This is quite a neat way to automatically enable or disable buttons on your view.<br />
<br />
<script src="https://gist.github.com/vermegi/7855057.js"></script><br />
<br />
Databinding to all this, is now quite easy from the view.<br />
<br />
<script src="https://gist.github.com/vermegi/7855077.js"></script><br />
<br />
Using this pattern we get a better separation of concerns in our application. The only thing to watch out for is the danger of your ViewModels getting too big. Keep in mind that the ViewModels' purpose is to shape the data of the Model specifically for a certain View. This means that most of the logic will be the responsibility of the Model, and not necessarily of the ViewModel.<br />
<br />
The advantage will be that you can put both Model and ViewModel in your portable class library, giving you the ability to reuse all of the logic between different platforms. And since both Model and ViewModel can be unit tested, you gain a great advantage.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD8jg9T9f3-5adey9VzwUxwZLGxPr7mCKLNwiEt3yza0YX-oYWv6Y7P7PdAlCHdNRZlNgb7cBzDoA0Z_AS8L2pjtG54WAXGOrCsn_4ySnlcAjnh3Iyu4QIP5vqRbcK0uJf9qIr4vWNjgw/s1600/MVVM_PCL.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD8jg9T9f3-5adey9VzwUxwZLGxPr7mCKLNwiEt3yza0YX-oYWv6Y7P7PdAlCHdNRZlNgb7cBzDoA0Z_AS8L2pjtG54WAXGOrCsn_4ySnlcAjnh3Iyu4QIP5vqRbcK0uJf9qIr4vWNjgw/s320/MVVM_PCL.png" width="320" /></a></div>
<br />
<br />
But we will still have to add some extra techniques if we want the ViewModel to be able to use platform specific services. For this we will introduce dependency inversion in the next part of this series.<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<div>
<br /></div>
<parts></parts>Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-16318002195360101562013-12-03T22:38:00.000-08:002013-12-17T06:15:14.317-08:00Building a cross platform solution for Windows Phone and Windows 8. Part II: The class library approachPrevious parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<previous parts=""></previous><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<br />
In the previous part of this series, you learned about linked files. While these are a good technique for quickly sharing pieces of code of your application, I prefer using a class library for shared functionality. The problem is however, you cannot use a regular class library in Windows Phone or Windows 8. What you can use though is a portable class library. This is a special kind of class library that makes it possible for you to target multiple platforms.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc9ixOc8Udhz3Ujjz_txqkYCT3PTJuxAFTWqZZkMIQ1X65Fz-BUVSbGI4YCcMwIo8yFa7KXZ-T1DNdE6fQNgKXPWJ5KbYBXKGx7XpjqT6IzsIQgLOeaLyLJpmKGdMWPNLcZQXK7812td8/s1600/PCL.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc9ixOc8Udhz3Ujjz_txqkYCT3PTJuxAFTWqZZkMIQ1X65Fz-BUVSbGI4YCcMwIo8yFa7KXZ-T1DNdE6fQNgKXPWJ5KbYBXKGx7XpjqT6IzsIQgLOeaLyLJpmKGdMWPNLcZQXK7812td8/s320/PCL.png" width="320" /></a></div>
<br />
What you will get when using a portable class library is the greatest common divisor between platforms of functionalities you will be able to use.<br />
<br />
For creating one, you can chose 'Portable Class Library' as a project template.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNX5nwV8ki9_7H-4V80WVJCjUfI5tjz1086jM8pPKe22jEVRPhz4HyYBBmVMpwiCwMJnq-gHvI8tJSMtFsA8mT_bU_owx9tLQ1D8YNWJuhv5kw1gwNKloYGPSkXswyApy1aPHocFT-XAc/s1600/PCL3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNX5nwV8ki9_7H-4V80WVJCjUfI5tjz1086jM8pPKe22jEVRPhz4HyYBBmVMpwiCwMJnq-gHvI8tJSMtFsA8mT_bU_owx9tLQ1D8YNWJuhv5kw1gwNKloYGPSkXswyApy1aPHocFT-XAc/s400/PCL3.png" width="400" /></a></div>
<br />
<br />
When creating the PCL you will get an additional pop up asking you for the platforms you wish to target with your portable class library.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiksduKz8wuLwJelZBUNLD9he-LsVWeUK1ibZgboVRNshVYaR5JbwBE1x_DaNL3gOVbWfRt_xl_6o6pJNafSl88-HIXphTHXhuZlG2tRgOobjv0sLhVyf8QgofaJ4PrbFrvEwGSUGrL3_E/s1600/PCL4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiksduKz8wuLwJelZBUNLD9he-LsVWeUK1ibZgboVRNshVYaR5JbwBE1x_DaNL3gOVbWfRt_xl_6o6pJNafSl88-HIXphTHXhuZlG2tRgOobjv0sLhVyf8QgofaJ4PrbFrvEwGSUGrL3_E/s320/PCL4.png" width="283" /></a></div>
<br />
<br />
In our case choosing Windows Phone and Windows 8 will suffice. For Windows Phone you might also choose to target at least version 7.5 or 8. The higher the version you choose the more possibilities you will have in your portable class library. This is due to the fact that Windows Phone 7 doesn't support the entire .Net framework, so you will bump into some coding restrictions when specifying Windows Phone 7. I myself, most of the time, choose at least version 7.5, just for convenience and since I assume most Windows Phone 7 users will have by now upgraded to this free version.<br />
<br />
So, now we have a place to put all of our shared code. But, what will this shared code be? It's not like we can put the code behind pages of the XAML files in this class library. So we will have to take the not so conventional path and make use of an additional pattern which will make it possible for us to put the business logic of our application in the shared class library. This pattern will be the MVVM pattern, since it can very easily be used in databinding scenarios and since it gives us a reactive user interface with INotifyPropertyChanged. This will be explained in the next part of this series.<br />
<br />
You can find additional information on Portable Class Libraries <a href="http://blogs.msdn.com/b/dsplaisted/archive/2012/08/27/how-to-make-portable-class-libraries-work-for-you.aspx">here</a>.<br />
<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-91464073135843397222013-12-02T07:16:00.001-08:002013-12-17T06:14:48.985-08:00Building a cross platform solution for Windows Phone and Windows 8. Part I: Quick sharing of codeThe intro to this series you can find <a href="http://proq.blogspot.com/2013/12/building-cross-platform-solution-for.html">here</a>.<br />
<br />
If you want to be able to quickly share things between a Windows Phone and Windows 8 application, you can always use the technique of linked files. Linked files are existing files you add to a project, for instance a file that already exists in your Windows 8 project and which you want to add to your Windows Phone project. But, instead of adding this existing file in the normal way, you add it as link. This is an additional option you can choose in the 'add existing item' dialog box.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdo1WuRiK5jx9iXl-UPWdLbVldOUWjveFBbeVQAOinFlgeHGMw7tJImwHxosoUQt6hkapeeCeTKtC8nenCK4ZVSpH50RuppbB3UYY8rtBtk1Lsk-4y-jGd-PqOhL8Xi4WwkgOFkDxkwJ4/s1600/AddAsLink.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdo1WuRiK5jx9iXl-UPWdLbVldOUWjveFBbeVQAOinFlgeHGMw7tJImwHxosoUQt6hkapeeCeTKtC8nenCK4ZVSpH50RuppbB3UYY8rtBtk1Lsk-4y-jGd-PqOhL8Xi4WwkgOFkDxkwJ4/s400/AddAsLink.png" width="365" /></a></div>
<br />
This will give you this same file in your other project, but not as a copy. Meaning that if you make a change to the file in one of the two projects, you will see this change reflected in the other project as well.<br />
<br />
You can use this technique for reusing code files or for reusing XAML files. But, as stated in the intro of this series, with XAML files you will have to:<br />
<ul>
<li>remove any platform specific namespaces.</li>
<li>only reuse small pieces of XAML (you will for instance see that for pages the start tag in your XAML is different, for Windows Phone this is a PhoneApplicationPage, for Windows 8 this is a Page tag).</li>
</ul>
If you use the technique of linked files for sharing code files, you can additionally use partial classes to cope with any platform differences. The shared code you can put in a partial class that you add as a linked file for the other platform. You then add another partial class file (with the same class name of course) in each project with the platform specific stuff. If you don't like partial classes that much, you can also choose to use inheritance for this. You will add your base class as link and create child classes with platform specific code in them.<br />
<br />
Another technique for coping with platform differences when using linked files is the use of preprocessor directives. These look like if-statements you put in between your code. They will contain the lines that are specific for a certain platform.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> public static void Initialize()
{
#if WINDOWS_PHONE
if (UIDispatcher != null)
#else
#if NETFX_CORE
if (UIDispatcher != null)
#else
if (UIDispatcher != null && UIDispatcher.Thread.IsAlive)
#endif
#endif
{
return;
}
#if NETFX_CORE
UIDispatcher = Window.Current.Dispatcher;
#else
#if WINDOWS_PHONE
UIDispatcher = Deployment.Current.Dispatcher;
#else
UIDispatcher = Dispatcher.CurrentDispatcher;
#endif
#endif
}
</code></pre>
<br />
(The above code is courtesy of <a href="http://mvvmlight.codeplex.com/">MVVMLight</a>, a very good starter framework for doing MVVM).<br />
<br />
As you can see in the above code snippet, there are some specific if-statements, called preprocessor directives, added. The ones for NETFX_CORE indicate to the compiler the lines of code that need to be compiled for Windows 8. The WINDOWS_PHONE ones will be compiled for Windows Phone. This can help you add platform specific code as well.<br />
<br />
With the technique of linked files you can get quite some reuse of code between Windows Phone and Windows 8 applications. You can also use partial classes, inheritance or preprocessor directives to add platform specific code. But I do want to point out the following flaws in using this technique (and this is why I don't prefer using it myself):<br />
<ul>
<li>Each technique (partial classes, inheritance, preprocessor directives) makes it hard to unit test your code, since it directly contains platform specific code.</li>
<li>Preprocessor directives, especially when used a lot, make it harder for you to read and understand your code (I've had projects going from a couple of preprocessor directives in one file to multiple and thus even more unreadable code).</li>
</ul>
In the following parts of this series, I will show you another technique for adding platform specific code, that will, at the same time, keep your code cleaner, more readable, more reusable and more maintainable (now, wouldn't that be nice).<br />
<br />
<br />
Other parts in this series:<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<br />
<parts></parts>Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com3tag:blogger.com,1999:blog-4315928131887373364.post-5900266512723708332013-12-01T12:09:00.002-08:002013-12-17T06:14:22.134-08:00Building a cross platform solution for Windows Phone and Windows 8This is Part 0 of a multi-part series blog post. In this series I will give you a walk through of how you can build a cross platform solution that targets both Windows Phone and Windows 8. I will try and give you pointers on how to keep your code as reusable and clean as possible. We will especially look at a couple of patterns and good practices for this. And in the mean time you will get to know some more advanced MVVM.<br />
<br />
But before we start, what are actually the problems you face when trying to target two platforms like Windows Phone and Windows 8? They are both XAML based, right, so this shouldn't be too big of a problem. Well, although both platforms are on the path of convergence, meaning moving towards each other, there are still quite some differences you need to take into account.<br />
<br />
One of those differences is the actual XAML you can use on each platform. Although the controls on each platform might be the same, they often live in different namespaces. There are also controls that are specific to either Windows Phone - like the PivotControl - or to Windows 8 - like the FlipView control.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8LBGEnl3AtT9dKLXufM19jsRup5GH_r6hse6ydsgMV8CKvydVl60U-YZfY_JFwmrKaGAymKi8W06Pxz8o9FT3hj-F6zpHI4wVey5dBV-qoRtbLFBEYQotBMtyn_NMW5mBGUCb5iJSILc/s1600/Sharable+controls.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="317" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8LBGEnl3AtT9dKLXufM19jsRup5GH_r6hse6ydsgMV8CKvydVl60U-YZfY_JFwmrKaGAymKi8W06Pxz8o9FT3hj-F6zpHI4wVey5dBV-qoRtbLFBEYQotBMtyn_NMW5mBGUCb5iJSILc/s320/Sharable+controls.png" width="320" /></a></div>
<br />
<br />
<br />
This makes sharing your XAML less obvious.<br />
<br />
I wouldn't recommend sharing too much of your XAML between Windows Phone and Windows 8 applications Anyway. You will see that you will mostly try and build a UX experience that is specific for the platform at hand. Keep in mind as well that both platforms support quite different form factors. The things that will be most easy to share will be small pieces of XAML - like things you put into user controls or small data templates.<br />
<br />
Apart from differences in your XAML you will also see differences in the actual API's you can use from Windows Phone and Windows 8. Both for instance provide you with an API for navigating between pages in your application, but if you look at the actual Navigate call for each platform, you will find that the call takes different parameters.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoUi0350S4negVUyuiC_MdrOnp8sd31S8nbpcp9h-uiyqtfvRheZwdlpmBmHxD0gku7P8taFht9_X3NttRyrLEUgxyQHYe_M39z9JKvOE2gBkKAzR8QgzAYUvzxTz-hY3ZnzCP27PjJnQ/s1600/WinRT_WP.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoUi0350S4negVUyuiC_MdrOnp8sd31S8nbpcp9h-uiyqtfvRheZwdlpmBmHxD0gku7P8taFht9_X3NttRyrLEUgxyQHYe_M39z9JKvOE2gBkKAzR8QgzAYUvzxTz-hY3ZnzCP27PjJnQ/s320/WinRT_WP.png" width="290" /></a></div>
<br />
<br />
This makes it less obvious to share code between the two platforms. However, later in this series, I will show you a technique that will give you quite some advantages for reusing for instance your navigation code.<br />
<br />
We just have to use a couple of techniques to get around these differences. I will try and give you some pointers in this series. Mainly I want you to get to know some techniques that will allow you to reuse as much of your business logic (the heart of your application) as possible while targetting multiple platforms.<br />
<br />
In this series you will find the following parts (and hopefully, if time permits, more to come):<br />
<br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for.html">Part 0: Intro</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_2.html">Part I: Quick sharing of code</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_3.html">Part II: The class library approach</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_8.html">Part III: We need a pattern</a><br />
<a href="http://proq.blogspot.be/2013/12/building-cross-platform-solution-for_15.html">Part IV: Mocking out the differences</a><br />
Part V: Event to command<br />
Part VI: Behaviors for coping with orientation changes<br />
Part VII: Tombstoning<br />
<div>
<br /></div>
I also recently did a talk on this topic at the <a href="http://www.mctsummit.eu/">2013 MCT Summit</a>, which got filmed. I hope I can soon add the video of it to this series, so you have some extra reference material there. Other extra reference material to come:<br />
<br />
<ul>
<li>A list of useful links on cross platform development</li>
<li>The slides of my 2013 MCT Summit talk</li>
<li>The start of a little framework you can use to build applications that target Windows Phone and Windows 8 (work in progress for now)</li>
</ul>
<div>
So, hope to see you soon for the first part in this series! I'll keep you posted!</div>
<div>
<br /></div>
<br />
<br />Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com2tag:blogger.com,1999:blog-4315928131887373364.post-72580874190334599582013-08-16T05:52:00.000-07:002013-08-16T05:52:37.949-07:00Automated JavaScript tasks with GruntI am currently working on a JavaScript only project and was looking for a way to automate some of the JavaScript processes. I was primarily looking for a way to get my tests automated, more or less the same as when you check-in code, your tests get automatically run.<br />
<br />
For this I chose <a href="http://gruntjs.com/">grunt</a>, which can easily execute different tasks, not only can it automate your test runs, but it can also automate other JavaScript tasks, like minifying your files, running them through jslint, ... You can find a complete list on the grunt site.<br />
<br />
The project I am working on is a Windows 8 application (not XAML this time, but JavaScript, HTML5, ...). So I am working in a .Net environment with a solution and a couple of projects.<br />
<br />
<h3>
Grunt Basics</h3>
<br />
To get started with grunt, first thing you will need to do is install <a href="http://nodejs.org/">node</a>. All tasks you will be running in grunt will need to be installed using nodes packaging system <a href="https://npmjs.org/">npm</a> (you can compare npm to the gem install process in ruby or nuget in .Net). After installing node, you can install grunt using npm. Once you've done this, you can start creating a grunt file in your web projects. A grunt file contains different tasks that need to be run, like uglify, jslint, minify, ...). You can find all info on getting started <a href="http://gruntjs.com/getting-started">here</a>.<br />
<br />
<h3>
Running jasmine tests with grunt</h3>
<div>
<br /></div>
<div>
Now, the thing I wanted to be able to do, was run my <a href="http://pivotal.github.io/jasmine/">jasmine</a> tests though grunt. For this I have some simple jasmine tests set up. I could already run these through the jasmine browser runner. I also tried out a setup that ran my jasmine tests browserless through <a href="http://phantomjs.org/">phantomjs </a>and with the help of the build in <a href="http://www.jetbrains.com/resharper/">Resharper </a>runner, which works great. </div>
<br />
For running these same tests with the help of grunt I needed to install a couple of extra grunt tasks through npm: <a href="https://npmjs.org/package/grunt-contrib-jasmine">contrib-jasmine</a> and <a href="https://npmjs.org/package/grunt-contrib-connect">contrib-connect</a>. The first one, obviously is needed to run your jasmine tests. The second one, connect, can be used to set up a browserless environment for grunt, so it won't start up a browser session with every run of your grunt file. Connect can also be replaced by node itself.<br />
<br />
The grunt file itself contains tasks for connect and jasmine:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jasmine: {
src: '<%= pkg.name %>.Web/*.js',
options: {
vendor: ['<%= pkg.name %>.Web/Scripts/*.js', '<%= pkg.name %>.Web/lib/*.js'],
host: 'http://127.0.0.1:<%= connect.test.port %>/',
specs: '<%= pkg.name %>.Web/specs/*.js'
}
},
connect: {
test: {
port: 8000,
base: '.'
}
}
});
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-contrib-connect');
// Default task(s).
grunt.registerTask('default', ['connect', 'jasmine']);
};
</code></pre>
<br />
You can see that in the jasmine task, I use the port number of my connect task. In my default task, at the bottom of the file, I first fire up the connect port and once that one is running, I let grunt run my jasmine tests.<br />
<br />
Once I now issue the grunt command at the command line,I can see it running my tests.<br />
<br />
<h3>
One step further: automated build</h3>
<div>
<br /></div>
<div>
Running my jasmine tests locally this way, is cool by itself, but it would be even nicer if I could integrate this in some sort of automated build process. Ie. check-in my code, trigger the grunt task runner, which will run my tests, run jslint, run uglify, ... Basically, get a finished product at the end of the pipeline. </div>
<div>
<br /></div>
<div>
The project I am working on right now, I got it using <a href="http://tfs.visualstudio.com/">tfsservice</a>, since I wanted to find out what its' pro's and cons are. This means, for automating my build, I had to rely on msbuild to do the trick for me. Now, tfsservice has got iisnode installed on it, so it should be possible to have it run grunt tasks as well. </div>
<div>
<br /></div>
<div>
To get this working, I altered some things in my grunt setup. First of all, I reinstalled grunt and all the packages it uses, so that they got saved locally into my project. This means reissuing the npm install command for grunt, contrib-jasmine, ... but WITH the --save-dev option. This will create a packages folder inside your project with all necessary files for each plugin saved locally inside your project. Once you commit your project to your source control system, all packages will also be present locally on the build server and don't need to be installed globally on your build server (something you just cannot do on tfsservice, being, that you're not sure on which build server you will be running next, which means reinstalling all packages with every run, which is just time consuming. You just don't want to do that.). </div>
<div>
<br /></div>
<div>
I additionally installed the grunt-cli package locally (so, again, with the --save-dev option). Grunt-cli is the grunt command line interface. It gives you the grunt command locally (read: on your build server). </div>
<div>
<br /></div>
<div>
Once you have done this, you can alter your csproj file of the project you want to use grunt in (remember: I am working in a .Net context here). For this, I added an additional target at the end of my csproj file: </div>
<div>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <Target Name="RunGrunt">
<Exec ContinueOnError="false" WorkingDirectory="$(MSBuildThisFileDirectory)\.." Command="./node_modules/.bin/grunt --no-color" />
</Target>
</code></pre>
<br /></div>
<div>
This target uses my locally installed version of grunt. The --no-color option I added to get the grunt output nicely formatted. If you don't add this option, your output will look pretty messy.<br />
<br />
You will also need to tell your build process to also run grunt after your build. So also add:<br />
<br /></div>
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: #eeeeee;"><Project ToolsVersion="4.0" DefaultTargets="Build;</span><span style="background-color: yellow;">RunGrunt</span><span style="background-color: #eeeeee;">" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</span></code></pre>
<div>
<br /></div>
<div>
After these alterations, you will see your grunt output in the output window of Visual Studio after building your project. This should also make it possible to automatically run grunt on my tfsservice.<br />
<br />
For this I made a build definition for my tfsservice. After checking in my code, the grunt task gets run as well, only, for now, it exits with errors (return fs.existsSync(filepath);<br />
^<br />
TypeError: Object #<object> has no method 'existsSync'). I looked in to these errors and apparently they are due to the fact that tfsservice doesn't use the latest version of node. I asked the tfs team if they could fix this and they promised me they'd get it done by the end of the month. So, for now, I'm still hoping to get this up and running in a couple of weeks. Normally, once node gets upgraded, there shouldn't be a problem. </object><br />
<br />
<br />
<br />
<br /></div>
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com4tag:blogger.com,1999:blog-4315928131887373364.post-5822279944199385222013-05-03T10:28:00.002-07:002013-05-03T10:28:28.419-07:00Testing an Aspnet MVC app with Ruby<h3>
Why testing through the UI is hard(ly done)</h3>
<br />
Writing UI tests for a web application can be quite cumbersome and is a painstakingly repetitive task. Also, the UI of an application tends to change often during development, making UI tests a brittle resource. To top this, when running UI tests, you need to count on a browser to act as a host for them, making them a lot slower than regular unit tests.<br />
<br />
It is for these and other reasons that people often don't go through the trouble of writing UI tests. And they are, in my opinion, right to do so.<br />
<br />
But still, I have seen a lot of applications break in the UI after making minor changes. If these errors don't pop up in your staging environment, you are left with a red face once you deploy to production (and yup, I have seen this happening too often, to not take steps to fix this). And no, people don't always go through the entire application when it's on the staging environment. The times where I've seen full test plan execution for an application, before it is allowed to go through to production, can be counted on (less than) one finger. The only fallback we have here are our unit tests and as the name says, they are for testing (small) units, not entire applications (read: end-to-end testing).<br />
<br />
There are of course testing frameworks you can use to run your UI tests, Selenium being one of them. I have been using Selenium on a couple of projects, but often give up quickly because of the slowness of the tests, because tests are hard to maintain, ... and so on.<br />
<br />
Now, I recently followed the <a href="http://www.accu.org/index.php/conferences/accu_conference_2013/accu2013_sessions#ruby_and_rails_for_n00bs">Ruby and Rails for n00bs</a> session of my good friend Michel (@michelgrootjans) and got introduced to a couple of Ruby test gems that actually open up a couple of opportunities you can use in your .NET applications as well.<br />
<br />
In this blog post I want to give you an overview of how you can set these Ruby test gems up, so they can run UI tests for an ASP .NET MVC application (or any .NET web application that is). The technologies (and gems) I will be describing here are:<br />
<ul>
<li>Ruby (of course)</li>
<li>RSpec</li>
<li>Capybara</li>
<li>Selenium</li>
<li>PhantomJS</li>
<li>Poltergeist </li>
</ul>
<br />
<h3>
Setting up the test environment</h3>
<br />
First of all, let's get our environment setup. For this, you will need Ruby, which you can find <a href="http://rubyinstaller.org/">here</a>. Once installed, you can test if all went well by running the following command from the command line:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>irb
</code></pre>
<br />
This should open up a Ruby REPL loop where you can test out statements (for instance 1+1, should give you the answer of 2).<br />
<br />
Once this is setup. Exit the REPL loop and start installing all the necessary gems:<br />
<br />
gem install rspec<br />
<br />
gem install capybara<br />
<div>
gem install selenium-webdriver</div>
<div>
gem install poltergeist<br />
<br />
One other thing we now need to install is PhantomJS, which you can find <a href="http://phantomjs.org/">here</a> and Firefox (which is used by the default selenium web driver, I will give you other options further down this blog post). And that's all we need to get started.<br />
<br />
<h3>
Writing a first test with rspec</h3>
</div>
<div>
<br />
We can now start writing tests. Our tests will be placed in separate _spec.rb files in a spec folder. For instance if you want to write specification tests for customers, you will have a customers_spec.rb file, for products, you will have a products_spec.rb file. Of course you are free to use whatever naming and grouping of your specification tests, just make sure you have a spec folder with in it at least one _spec file.<br />
<br />
A spec looks like this:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>describe 'adding a new customer' do
it 'should be able to create a new customer' do
end
end
</code></pre>
<br />
As you can see, you start of with a describe, which tells what kind of behavior you want to test. The it part contains the expected outcome (we will add this later). Don't worry about the Ruby syntax for now. For people using a BDD-style testing framework the describe and it syntax should look familiar.<br />
<br />
The things we will want to test, are going to be the behavior of a website. For this we will use the capybara and selenium gems. And since we want this first spec and all following specs to be using the same setup for our tests (eg. url of the site we will be testing), we will use a spec_helper.rb file for this. In this file we will require all the necessary gems and do all of the setup. Each individual spec file will then require this one spec_helper file:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>require 'capybara/rspec'
require 'selenium/webdriver'
Capybara.run_server = false
Capybara.default_driver = :selenium
Capybara.app_host = 'http://localhost/TheApplication'
</code></pre>
<br />
After the require statements, we configure capybara. First of all, we tell it to not run its server. Since capybara is essentially a rails testing framework, it runs under a rack application by default. We won't have this, since our app will be running in IIS (Express) or something similar. Next we tell it which driver to use and last where our application is located (you could test www.google.com if you'd like).<br />
<br />
Now that we have this setup, we can start writing a first test. Capybara actually allows you to click buttons and fill out fields in a web application, and that's what we will be doing:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>require 'spec_helper'
describe 'adding a new customer', :type => :feature do
it 'should be able to create a new customer' do
visit '/Customer'
click_link 'Add'
fill_in('first_name', :with => 'Gitte')
fill_in('last_name', :with => 'Vermeiren')
fill_in('email', :with => 'mie@hier.be')
click_button 'Create'
page.should have_text 'New customer created'
end
end
</code></pre>
<br />
As you can see, capybara has methods for clicking links, filling out fields, choosing options, ... and in the end for testing whether you get an expected outcome in your application. You can find the capybara documentation with additional capabilities <a href="https://github.com/jnicklas/capybara">here</a>.<br />
<br />
Also notice I added the :type => :feature hash to the describe, so the test will be picked up as an rspec test.<br />
<br />
Once you have this spec file, you can actually run your test. For this fire up a command prompt, cd to the directory just above your spec directory and run the rspec command:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>rspec
</code></pre>
<br />
You will notice this command will take a bit to start up, but once it's running, it will start up a firefox window and show you an error in the command prompt, since I assume you don't have anything implemented yet to get the above test to succeed. I leave it up to you, the reader, to write a small web app to get this test passing. Once you have this and you run the rspec command, you will see the different fields in your browser filled out with the values you specified in your test.<br />
<br />
<h3>
Improving our test</h3>
<div>
Now, I promised you, the return on investment with rspec, capybara, ruby, ... would be worth the effort. First of all, I can tell you from experience that the above capybara test is a lot cleaner than comparable tests written in .NET. But above that, we can do more. </div>
<div>
<br /></div>
<div>
We can start of by having our tests run headless, meaning that we won't be needing a browser window anymore. For this we will use poltergeist and phantomjs. You will need to alter the spec_helper file for this:</div>
<div>
<br /></div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>require 'capybara/rspec'
require 'selenium/webdriver'
require 'capybara/poltergeist'
Capybara.run_server = false
Capybara.default_driver = :selenium
Capybara.javascript_driver = :poltergeist
Capybara.app_host = 'http://localhost/TheApplication'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app,
:phantomjs => 'C:\\some_path\\phantomjs.exe')
end
</code></pre>
<br />
This adds the extra requirement for poltergeist and adds the javascript_driver configuration setting. Additionally we tell capybara where it can find the phantomjs process.<br />
<br />
You will also need to add the :js => true hash to your describe statement for it to run in phantomjs:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>describe 'adding a new customer', :type => :feature, :js => true do
</code></pre>
<br />
If you run your tests now with rspec, you will notice, firefox will not run, you will just get a summary in the command prompt of which tests succeeded or failed.<br />
<br />
I ran some tests with our own web application and noticed that the headless tests ran twice as fast as the tests using the browser.<br />
<br />
<h3>
Further improvements</h3>
<div>
I am actually already quite happy with this first test setup. It's still not the fastest running tests, but it does allow me to get in some easy end-to-end testing, or to even start doing some BDD style testing with this. You can also use cucumber if you'd want to to instead off rspec. </div>
<div>
<br /></div>
<div>
In my own setup I extended the above example with some extra configuration settings to be able to easily switch my testing environment from my local to the staging environment and from headless to browser testing. </div>
<div>
<br /></div>
<div>
I also did some tests with chrome (doable) and IE (very, very slow test runs!), but for now prefer the firefox and headless setup. </div>
<div>
<br /></div>
<div>
I would also like to add some extra stuff to setup and clear my database before and after each test. That is something I haven't figured out yet, but should be easily added. </div>
<div>
<br /></div>
</div>
<div>
<br /></div>
Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com1tag:blogger.com,1999:blog-4315928131887373364.post-7419816955111799882013-02-11T10:03:00.001-08:002013-02-11T10:03:01.924-08:00A Better Dispatcher with the Factory FacilityIn the applications we write, we often use the same principles. First off, there is<a href="http://martinfowler.com/articles/injection.html"> dependency injection</a>, preferably through the constructor of a class. Second we often use <a href="http://martinfowler.com/bliki/CommandQuerySeparation.html">CQS</a>, to get a clear separation between the commands and queries of our application.<br />
<br />
For implementing CQS we often utilize some kind of a dispatcher. This is a simple class which has Dispatch methods for commands and queries. We can use it like so:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public class DoubleAddressController : Controller
{
readonly IDispatcher _dispatcher;
public DoubleAddressController(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public ActionResult GetExistingFilesForAddress(FindDoubleAddressRequest request)
{
var result = _dispatcher.DispatchQuery<FindDoubleAddressRequest, FindDoubleAddressResponse>(request);
return PartialView(result);
}
}
</code></pre>
<br />
We ask the dispatcher to dispatch a query for a certain request and response. I ommitted error handling and additional mapping from the above example.<br />
<br />
So, the dispatcher gets a certain command or query as an argument and based on this needs to ask a certain query or commandhandler to handle this command or query. Up untill now I used the IoC repository to get hold of this queryhandler:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public class Dispatcher : IDispatcher
{
readonly IWindsorContainer _windsorContainer;
public Dispatcher(IWindsorContainer windsorContainer)
{
_windsorContainer = windsorContainer;
}
public TResponse DispatchQuery<TRequest, TResponse>(TRequest request)
{
var handler = _windsorContainer.Resolve<IQueryHandler<TRequest, TResponse>>();
if (handler == null)
throw new ArgumentException(string.Format("No handler found for handling {0} and {1}", typeof(TRequest).Name, typeof(TResponse).Name));
try
{
return handler.Handle(request);
}
finally
{
_windsorContainer.Release(handler);
}
}
}
</code></pre>
<br />
The dispatcher has a dependency on our IoC container, in the example above a WindsorContainer, and asks this container to get hold of the specific handler that can handle the request we just got in.<br />
<br />
With this solution however there are a couple of problems. First of all, we need a dependency on our IoC container (in the IoC configuration we configure the container with a reference to itself). Second, we resolve a dependency from the container, which is just not done (service location is known as an anti-pattern). And we need to think about releasing the handler dependency we just resolved. Something the developer needs to think about and which I've seen forgotten.<br />
<br />
So, there should be a better solution for this, and there is! I recently started a refactor on another piece of code which used a factory to get hold of instances and which did not make use of our Castle Windsor container. I started looking at the <a href="http://docs.castleproject.org/Windsor.MainPage.ashx">Castle Windsor</a> documentation and you can actually configure it with classes which act as factory and with a <a href="http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx">factory facility</a>. After this refactoring I thought this factory facility might as well be usable for our not so ideal dispatcher.<br />
<br />
First we got rid of the WindsorContainer dependency in the dispatcher:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public class Dispatcher : IDispatcher
{
private readonly IFindHandlersFactory _handlerFactory;
public Dispatcher(IFindHandlersFactory handlerFactory)
{
_handlerFactory = handlerFactory;
}
public TResult Dispatch<TRequest, TResult>(TRequest request)
{
var handler = _handlerFactory.CreateFor<TRequest, TResult>(request);
if (handler == null)
throw new HandlerNotFoundException(typeof(IQueryHandler<TRequest, TResult>));
return handler.Handle(request);
}
}
</code></pre>
<br />
We now use a IFindHandlersFactory. A factory which just finds handlers for us. This interface just has one method defined, CreateFor, with generic type parameters. The thing is that we will not make an implementation for this interface. This interface will be configured in our Castle Windsor container as a factory.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
container.AddFacility<typedfactoryfacility>();
container
.Register(
Component
.For<IDispatcher>()
.ImplementedBy<Dispatcher>()
.LifestyleTransient())
.Register(
Component
.For<IHandlerFactory>()
.AsFactory()
.LifestyleTransient())
;
</code></pre>
<br />
Once you have done this, Castle Windsor will automatically resolve your handlers, without you having to actually call Resolve for these dependencies.<br />
<br />Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-46144957305684559802012-11-01T07:47:00.002-07:002012-11-01T07:49:36.931-07:00Unit Testing a Windows 8 ApplicationI am a big fan of test driving an application. That's why I write almost no code without writing a test for it.<br />
<br />
I recently began writing a Windows Store application for Windows 8 and again wanted to test drive this app. If you look at MSDN at how to add a test project to you Windows 8 app, you will see, you can add a Windows Store test project to your solution. Now, handy as this is, the down sight is that this test project is as well a Windows Store project type, meaning you won't be able to add a whole bunch of references to it. I wasn't able to add RhinoMock or Moq to it, nor was I able to add MSpec. The problem being these frameworks were build to the wrong version of the .Net framework.<br />
<br />
Now, I could have made my own builds of the frameworks I am happy working with, but I started looking if there is no other way, like using a simple class library for unit testing a Windows Store app. Now, when you try this, the problem is, you can't get a reference of your Windows Store app added to your class library for testing.<br />
<br />
To get this fixed, I tried out a couple of things. First I tried adding the same references to my class library project as were in the Unit Test Library for Windows Store apps. This didn't work, however. Also, I couldn't find the '.NET for Windows Store apps' reference dll. I also tried playing around with the output type of my project. Changing it to something different than class library. But then again, adding the necessary unit testing references became a problem. I also played around with the conditional compilation symbols (hey, I was trying to find where the differences lay between my own class library and a Unit Test Library for Windows Store apps).<br />
<br />
After trying all that, I unloaded my project from solution explorer and started editing it, comparing it to the Unit Test Library for Windows Store apps and trying out different combinations. Now, after a couple of tries, the setting in your project file, you need is the following:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
</code></pre>
<br />
You can put this line as a replacement of the other csharp.targets file at the bottom of your project file. Once you have added this, you can add a reference of your Windows Store app to your class library. You will even see the '.NET for Windows Store apps' reference show up in your references. You will even be able to add all the additional references you want, like NUnit, Moq or RhinoMock, ...<br />
<br />
One additional problem I had was with the System.Data dll, which was build to a different framework. Since I didn't need it in my test project, I happily removed it.<br />
<br />
<br />Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-27104459877012014042012-09-03T12:20:00.000-07:002013-03-04T00:32:39.300-08:00WCF on IIS and Windows 8Just spend some time getting a simple WCF service up and running under IIS on my Windows 8 machine. Apparently, if you install IIS after installing the last .NET framework (ie. installing Visual Studio 2012), not all necessary handlers, adapters and protocols for WCF are installed on your IIS.<br />
<br />
First time I tried to reach the WCF service it gave me an error that said 'The page you are requesting cannot be served because of the extension configuration.' This means you need to run Servicemodelreg.exe to reregister WCF (same kind of registration you needed from time to time for ASP .NET on previous versions of IIS, remember aspnet_regiis). You can find this tool at C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation for version 3.0 or at C:\Windows\Microsoft.NET\Framework\v4.0.30319 for version 4.0.<br />
<br />
Now looking at the <a href="http://msdn.microsoft.com/en-us/library/ms732012.aspx">MSDN site</a>, they will tell you to run the 3.0 version. After doing so, however, you won't have the necessary handlers installed for a WCF service created with Visual Studio 2012, since they are all version 4.0. So that won't work.<br />
<br />
Running the 4.0 version however won't work either. If you try Servicemodelreg.exe -i it will tell you to register with the -c option (register a component). If you try the -i -c option you will get the error (and the solution!) that this tool cannot be used on this version of windows. What you can use, though, is the 'Turn Windows Features On/Off' dialog.<br />
<br />
So simply open this up from your control panel (I pinned my control panel to my start page on day one of installing Windows 8, otherwise I wouldn't be able to find it again) and check the necessary WCF features you want to have available on your WCF. In most cases, just flagging HTTP will do. You can find the WCF features under .NET Framework 4.5 Advanced Services.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje83wZAGuqkLl8Gkf_AShHVXRM3mcEkALnZHTFN0XVOd8CI-a8Wf-i_9E3ssX-26UansgvNtWDMOHzP81gxW0lc9SCeN1ILOdH41FFjia85ecFoPaY-uMtM2O4ozg2Uf-Wy9YeOv8-gpQ/s1600/wcf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje83wZAGuqkLl8Gkf_AShHVXRM3mcEkALnZHTFN0XVOd8CI-a8Wf-i_9E3ssX-26UansgvNtWDMOHzP81gxW0lc9SCeN1ILOdH41FFjia85ecFoPaY-uMtM2O4ozg2Uf-Wy9YeOv8-gpQ/s320/wcf.png" width="320" /></a></div>
<br />
And that's what you need to get yuor WCF service running under IIS on Windows 8. Hope this was helpful.<br />
<br />
Addendum: This fix recently also solved the issue of a 'HTTP Error 400. The request hostname is invalid' error of a colleague when trying to run a WCF service on Windows 8.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com12tag:blogger.com,1999:blog-4315928131887373364.post-19233465266199184972012-07-14T05:09:00.000-07:002012-07-14T05:09:02.137-07:00Knockout an MVC Ajax callI recently needed to build an Ajax data search, showing the result of the search in an MVC web page. Great opportunity, I thought, to give <a href="http://knockoutjs.com/">Knockout.js</a> a try. Knockout.js lets you apply databindings to a web page and for this it uses an MVVM (Model View ViewModel) approach.<br />
<br />
On the knockout site, you can find some great examples to get started, even give it a try in <a href="http://jsfiddle.net/">jsFiddle</a>. But since my solution is a bit different from their tutorials, I wanted to share it with you.<br />
<br />
The actual problem at hand was a page on which I needed to link a scanned in document to a dossier. Most of the times the number of the dossier can be picked up from the scanned in document, but this is not always the case. In case where the number of the dossier can't be determined from the scan, we want our users to go look for the dossier and link the dossier manually to the scanned in document.<br />
<span style="background-color: white;"><br /></span><br />
<span style="background-color: white;">The page to do this more or less looks like this (I rebuild the solution without most of the formatting we have in the initial application).</span><br />
<span style="background-color: white;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0he9j3y9rs1TuOA_KP7A7N8YFNIS3ercgVMVZNLwNo70kvYVTd_yeXNNSOVy0RpaWB0I1fAtT_2ib9vQjpt6ix1xCHrdvcyyP8MnH6plT3oo940FsvCJCF2mDSVqO5zCiK8eEvX28qtU/s1600/Page.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0he9j3y9rs1TuOA_KP7A7N8YFNIS3ercgVMVZNLwNo70kvYVTd_yeXNNSOVy0RpaWB0I1fAtT_2ib9vQjpt6ix1xCHrdvcyyP8MnH6plT3oo940FsvCJCF2mDSVqO5zCiK8eEvX28qtU/s320/Page.png" width="320" /></a></div>
<br />
<span style="background-color: white;">The initial setup for this contains a ScanController that gives you this Scan Detail page.</span><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public class ScanController : Controller
{
public ActionResult Detail(int id)
{
var scan = new Scan
{
Id = id,
File = "This is the file",
DossierId = 0,
DossierNumber = string.Empty
};
return View(new ScanViewModel(scan, new Dossier()));
}
}
</code></pre>
<br />
This uses the Detail view, which consists of two divs for the accordion. The top div looks like this:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>@using (Html.BeginForm("Link", "Scan"))
{
&lt;div>
&lt;fieldset>
&lt;dl>
&lt;h2>Scan info&lt;/h2>
@Html.Label("Receipt date")
@Html.TextBox("receiptdate", string.Empty, new { @class = "date" })
&lt;/dl>
&lt;h2>Dossier info&lt;/h2>
&lt;div>
@Html.Hidden("file", Model.Scan.File)
&lt;div id="linkDiv" @(Model.Scan.DossierId == 0 ? "class=hidden" : "")>
&lt;div>Dossier: &lt;span id="dossierNumberText">@Model.Scan.DossierNumber&lt;/span>&lt;/div>
@Html.Hidden("dossierNumber", Model.Scan.DossierNumber)
&lt;input type="submit" value="Link Scan to this dossier"/>
&lt;/div>
&lt;div id="message" @(Model.Scan.DossierId == 0 ? "": "class=hidden")>
There is no dossier to link to. You should search for one.
&lt;/div>
&lt;/div>
&lt;/fieldset>
&lt;/div>
}
</code></pre>
<br />
The bottom div looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgChdd-C7H90lUI-szQS1gXadvPlSY-cGT502fs2mp4lRjSEK7hI4cPTvR4grJH2S3NWt0l5kvdKMGask6z1nn56B9eqkkqxm2xtScDhKaVh796QLIH3B-4e48E_WS2TwnwyCUMicLwjtk/s1600/Page2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgChdd-C7H90lUI-szQS1gXadvPlSY-cGT502fs2mp4lRjSEK7hI4cPTvR4grJH2S3NWt0l5kvdKMGask6z1nn56B9eqkkqxm2xtScDhKaVh796QLIH3B-4e48E_WS2TwnwyCUMicLwjtk/s320/Page2.png" width="320" /></a></div>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>&lt;div id="search">
@using(Html.BeginForm("Search", "Dossier", FormMethod.Post, new { @id = "dossierForm" }))
{
&lt;fieldset>
&lt;dl>
@Html.LabelFor(m => m.Dossier.DossierNumber)
@Html.TextBoxFor(m => m.Dossier.DossierNumber)
&lt;/dl>
&lt;dl>
@Html.LabelFor(m => m.Dossier.OwnerLastName)
@Html.TextBoxFor(m => m.Dossier.OwnerLastName)
&lt;/dl>
&lt;dl>
@Html.LabelFor(m => m.Dossier.OwnerFirstName)
@Html.TextBoxFor(m => m.Dossier.OwnerFirstName)
&lt;/dl>
&lt;dl>
&lt;input type="submit" value="Search"/>
&lt;/dl>
&lt;/fieldset>
}
&lt;/div>
&lt;div id="searchResult" class="hidden">
&lt;table id="resultTable">
&lt;thead>
&lt;th>DossierNumber&lt;/th>
&lt;th>OwnerLastName&lt;/th>
&lt;th>OwnerFirstName&lt;/th>
&lt;th>Detail&lt;/th>
&lt;th>Link&lt;/th>
&lt;/thead>
&lt;tbody>
&lt;/tbody>
&lt;/table>
&lt;/div>
</code></pre>
<br />
It's this bottom div that we are most interested in. The top form (Search Dossier) will be used to perform an Ajax search. The result of this search will have to be shown in the table of the bottom searchResult div.<br />
<br />
For this search I already added a Dossier controller with a Search action:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public class DossierController : Controller
{
public ActionResult Search(DossierSearchViewModel searchVm)
{
return Json(new
{
Success = true,
Message = "All's ok",
Data = new List&lt;Dossier>
{
new Dossier
{
DossierNumber = "123abc",
OwnerFirstName = "John",
OwnerLastName = "Doe"
},
new Dossier
{
DossierNumber = "456def",
OwnerFirstName = "Jeff",
OwnerLastName = "Smith"
},
new Dossier
{
DossierNumber = "789ghi",
OwnerFirstName = "Peter",
OwnerLastName = "Jackson"
},
new Dossier
{
DossierNumber = "321jkl",
OwnerFirstName = "Carl",
OwnerLastName = "Turner"
},
}
});
}
}
</code></pre>
<br />
If you click the Search button you will be get to see the Json result in the Dossier/Search page. This is not what we want, this form should perform an asynchronous Ajax post. That's not yet the case. For this I used the <a href="http://malsup.com/jquery/form/#getting-started">JQuery forms</a> plugin. Which has a handy ajaxForm method you can add to your form. (you could also use the mvc ajax extensions for this, they should already be in your initial MVC setup).<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>&lt;script type="text/javascript">
$(function () {
$("#dossierForm").ajaxForm({
success: render_dossier_grid
});
});
function render_dossier_grid(ctx) {
}
&lt;/script>
</code></pre>
<br />
All of the knockout magic can now be added in the render_dossier_grid function. Before we can do this, make sure to add the knockout.js files to your solution. This can be easily done using nuget. Reference them in your _layout file, so you can use them.<br />
<br />
First, let's create a viewmodel. This will be nothing more than a list of dossiers we get back from our dossier search. Since we want to be able to add and remove items from this list and at the same time have our table automatically show the new items, we will use a knockout observable array. To have the databindings applied to your view, you should call applyBindings for your viewmodel.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>$(function () {
$("#dossierForm").ajaxForm({
success: render_dossier_grid
});
<b><span style="color: blue;">ko.applyBindings(viewModel);</span></b>
});
function render_dossier_grid(ctx) {
}
<b><span style="color: blue;">var viewModel = {
dossiers: ko.observableArray([])
};</span></b>
</code></pre>
<br />
This viewModel can now be filled when we get the result of our Ajax call.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function render_dossier_grid(ctx) {
$("#searchResult").removeClass("hidden");
viewModel.dossiers.removeAll();
viewModel.dossiers(ctx.Data);
myAccordion.accordion("resize");
}
</code></pre>
<br />
That's pretty easy. I just reset the dossiers observable array of the viewmodel and add the dossiers that come from the Ajax call. Last bit is having the JQuery accordion control perform a resize, just to get rid of any scroll bars.<br />
<br />
Next step is actually binding this viewmodel to something. So, we need to specify in our view what data needs to go where. For this we will extend the table we have on our page.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>&lt;table id="resultTable">
&lt;thead>
&lt;th>DossierNumber&lt;/th>
&lt;th>OwnerLastName&lt;/th>
&lt;th>OwnerFirstName&lt;/th>
&lt;th>Detail&lt;/th>
&lt;th>Link&lt;/th>
&lt;/thead>
&lt;tbody <b><span style="color: blue;">data-bind="foreach:dossiers"</span></b>>
&lt;tr>
&lt;td <b><span style="color: blue;">data-bind="text:DossierNumber"</span></b>>&lt;/td>
&lt;td <b><span style="color: blue;">data-bind="text:OwnerLastName"</span></b>>&lt;/td>
&lt;td <b><span style="color: blue;">data-bind="text:OwnerFirstName"</span></b>>&lt;/td>
&lt;td>
&lt;a <span style="color: blue;"><b>data-bind="attr: {href: DetailLink}"</b></span>>Detail&lt;/a>
&lt;/td>
&lt;td>
&lt;a href="#" <b><span style="color: blue;">data-bind="click: $parent.useDossier"</span></b>>Use this file for linking&lt;/a>
&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
</code></pre>
<br />
Adding the databindings is not that hard. I added a foreach binding, which will make a new table row for each dossier in the dossiers observable array. Each table row has its own binding for each td element. The first three are quite obvious. You can databind to the names of the properties of your domain (or MVC viewmodel) object.<br />
<br />
For the second to last binding I added a databinding to the href attribute of an a tag. The DetailLink is a property on the Dossier domain object that gives you a link to Dossier/Detail/id.<br />
<br />
The last one is a special binding to the click event of an a tag. It is bound to the useDossier function of the parent of the binding. The parent of our binding is the actual viewmodel. We still need to add this useDossier function:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>var viewModel = {
dossiers: ko.observableArray([]),
useDossier: function (dossierVM) {
var dossierNumber = dossierVM.DossierNumber;
myAccordion.accordion({ active: 0 });
$("#dossierNumber").val(dossierNumber);
$("#dossierNumberText").text(dossierNumber);
$("#linkDiv").removeClass('hidden');
$("#message").addClass('hidden');
}
};
</code></pre>
<br />
In this function I use the viewmodel. In this case this is the actual row/dossier of the table. I take the DossierNumber of the current dossier and use it to set the value of the dossierNumber and dossierNumberText fields in the top piece of the accordion. I also do some extra bits to update the UI accordingly.<br />
<br />
That's it, not much to it. I really like this knockout framework. I did have some trouble to get started at first, but once you know your way around the viewmodel, it's pretty easy to use.<br />
<br />
The full code can be found on <a href="https://github.com/vermegi/KnockoutDemos">github</a>.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-71535007081371902692012-05-22T03:40:00.000-07:002012-05-22T03:40:07.523-07:00Async VII: WinRT class libraryIn the previous post I talked about async from JavaScript. Now, for this I had to make a WinRT class library for my asynchronous RestCaller class, so this functionality could be used from a HTML5 JavaScript WinRT application. Now, once you do this, there are some things you need to know and some restrictions on the types you use for your publicly visible methods.<br />
<br />
First of all you need to create a class library. Pretty simple, but once it's created, you need to change its' project type to WinMD file. This stands for Windows MetaData file.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYtqtKc1u2z0F9x_RFXjWSSNMZKpJwqvU6O2EKM2tZu3BrSSDw7OUgmN1iHbJkCtgyyl-pvka0PBK0LFR7a2S6yYKpb-hF3Ak6I7UkJPim7-6oZdzsnjMuAfz9TVoz3CJOE6uVD8oHpuU/s1600/WinMD.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="93" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYtqtKc1u2z0F9x_RFXjWSSNMZKpJwqvU6O2EKM2tZu3BrSSDw7OUgmN1iHbJkCtgyyl-pvka0PBK0LFR7a2S6yYKpb-hF3Ak6I7UkJPim7-6oZdzsnjMuAfz9TVoz3CJOE6uVD8oHpuU/s400/WinMD.png" width="400" /></a></div>
<br />
Also, in the first version, my class library was called BlitzHiker.Lib. This name gave me runtime errors when called from JavaScript. At compile time everything was fine, but at runtime it would just crash for no reason. Removing the point from its' name fixed this.<br />
<br />
Once I had the class library ready, I copied my RestCaller class to it and started compiling. The errors this gave were quite abundant. For starters, you are not allowed to use a return type of Task or Task&lt;T> in a WinMD file. This forced me to define all of my existing methods as private. Which made it all compile just fine. But then again, you're nothing with private methods, you need some public ones as well.<br />
<br />
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: yellow;">private </span><span style="background-color: #eeeeee;">async Task PublishHikeRequestTaskAsync(CancellationToken token)
{
var hikeRequest = GetHikeRequest();
try
{
var client = new HttpClient();
var url = string.Format("{0}/HikeRequest", BASE_URL);
var response = await client.PostAsync(url, await BuildJsonContent(hikeRequest), token);
response.EnsureSuccessStatusCode();
}
catch (HttpRequestException exc)
{
var dialog = new MessageDialog(exc.Message);
dialog.ShowAsync();
}
}
</span></code></pre>
<br />
For each of these private methods I needed to define a public wrapper. The return types you are allowed to use on them are AsyncAction (as a replacement for Task) and AsyncOperation&lt;T> (as a replacement for Task&lt;T>).<br />
<br />
The original method gets called by using AsyncInfo.Run (this changed in the recent CTP, the original type used was AsyncInfoFactory, but that one's gone. If you watch the Build sessions on async, you'll see them use the AsyncInfoFactory, but that just won't work anymore).<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public IAsyncAction PublishHikeRequestAsync()
{
return (IAsyncAction)AsyncInfo.Run((ct) => PublishHikeRequestTaskAsync(ct));
}
</code></pre>
<br />
You can also see me sending along a CancellationToken. Since it's not passed along to the PublishHikeRequestAsync method, you will have to use a different way of cancelling than I showed in one of the previous posts.<br />
<br />
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">protected async override void OnNavigatedTo(NavigationEventArgs e)
{
cts = new CancellationTokenSource();
try
{
await _restCaller.PublishHikeRequestAsync()</span><span style="background-color: yellow;">.AsTask(cts.Token);</span><span style="background-color: #eeeeee;">
var driverIds = await _restCaller.GetDriversAsync()</span><span style="background-color: yellow;">.AsTask(cts.Token);</span><span style="background-color: #eeeeee;">
if (driverIds != null)
await ShowDriversOnMap(driverIds, cts.Token,
new Progress&lt;int>(p => statusText.Text = string.Format("{0} of {1}", p, driverIds.Count)));
}
catch (OperationCanceledException exc)
{
statusText.Text = exc.Message;
}
}
</span></code></pre>
<br />
Since you get an AsyncAction, and not a Task, you can call AsTask on this. With AsTask, you can send along your CancellationToken. This shows that before you all start using WinMD class libraries, just keep in mind that you are working with different types and that the usage will be different (more verbose) as well.<br />
<br />
As for the AsyncOperation, that's pretty much the same as AsyncAction.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public IAsyncOperation&lt;UserModel> GetUserAsync(Guid userId)
{
return (IAsyncOperation&lt;UserModel>)AsyncInfo.Run((ct) => GetUserTaskAsync(userId, ct));
}
</code></pre>
<br />
And that's it. I hope you found these posts on async useful. Just keep in mind that all info given here is still based on a preview version of this library and things can still change a bit in the eventual release.<br />
<br />
There are some drawbacks on using async. As with a lot in the .NET Framework, they make things really simple for you. The danger is that it's easy to forget what you are actually doing, defining callbacks. Just keep that in mind and you'll be fine.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-27144991770677839692012-05-18T04:45:00.000-07:002012-05-18T04:45:32.097-07:00Async VI: JavaScript PromisesThe previous posts (<a href="http://proq.blogspot.com/2012/04/async-i-basics.html">Async basics</a>, <a href="http://proq.blogspot.com/2012/05/async-ii-exception-handling.html">Exception handling</a>, <a href="http://proq.blogspot.com/2012/05/async-iii-cancellation.html">Cancellation</a>, <a href="http://proq.blogspot.com/2012/05/async-iv-progress-reporting.html">Progress reporting</a>, <a href="http://proq.blogspot.com/2012/05/async-v-void-methods.html">void methods</a>) all talked about async from a C# point of view. But let's not forget there is another very important language coming to WinRT and that's JavaScript in combination with HTML5. The cool thing is you can use more or less the same async capabilities here that you find in C#. Big difference is the syntax you will be using. Since the async syntax will be closer to what you are used to in JavaScript.<br />
<br />
The UI in the JavaScript BlitzHiker application looks pretty much the same as its C# counterpart. It also has a page to publish a hikerequest, which does three big things, initialize the Bing map we use, find my own location and publish my hikerequest.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function initialize() {
initializeBing();
findMe();
publish();
}
</code></pre>
<br />
The findMe function has the first bit of asynchrony.<br />
<br />
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">function findMe() {
if (myPosition) {
setMePushpin(myPosition)
}
else {
if (!loc) {
loc = Windows.Devices.Geolocation.Geolocator();
}
if (loc) {
loc.</span><span style="background-color: yellow;">getGeopositionAsync</span><span style="background-color: #eeeeee;">()
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(setMePushpin, errorHandler);
}
}
}
</span></code></pre>
<br />
The call to GetGeopositionAsync is an asynchronous call. We can subscribe a callback to this method by using the then function. So no special keywords like await and async here, but more JavaScript style callbacks. You also see me using an error handler. In the JavaScript case, it is not with try catch that you handle exceptions, but with an extra error handler function you can send along.<br />
<br />
I also made use in this function of the loc variable, that I defined globally. My original version of this method looked like this:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function findMe() {
if (myPosition) {
setMePushpin(myPosition)
}
else {
Windows.Devices.Geolocation.Geolocator()
.getGeopositionAsync()
.then(setMePushpin, errorHandler);
}
}
</code></pre>
<br />
But funny enough only one times out of 10 the pushpin for my position was set correctly. This had me puzzled. Apparently, my local Geolocator had already gone out of scope before the callback came in. That is why I altered this to a global variable.<br />
<br />
Another place where I used asynchronous callbacks, is in the publish method, which publishes a hikerequest, gets all the drivers and shows those on the Bing map.<br />
<br />
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">function publish() {
var caller = new BlitzHikerLib.RestCaller();
caller.publishHikeRequestAsync()
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(function () {
caller.getDriversAsync()
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(function (driverIds) {
if (driverIds == null || driverIds.length == 0)
return;
for (var i = 0 ; i &lt; driverIds.length && i &lt; 200 ; i++) {
var driverId = driverIds[i];
caller.getUserAsync(driverId)
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(showDriver);
}
});
});
}
</span></code></pre>
<br />
You see me use then three times, each time sending a callback function along. Now, in my humble opinion, this syntax doesn't make this code the most readable code in the world. You need to look at it a couple of times to see what's going on. Now, you can actually improve on this by use of a little trick.<br />
<br />
<pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">function publish() {
var caller = new BlitzHikerLib.RestCaller();
cancellable =
caller.publishHikeRequestAsync()
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(function () {
</span><span style="background-color: yellow;">return caller.getDriversAsync()</span><span style="background-color: #eeeeee;">
})
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(function (driverIds) {
if (driverIds == null || driverIds.length == 0)
return;
for (var i = 0 ; i &lt; driverIds.length && i &lt; 200 ; i++) {
var driverId = driverIds[i];
caller.getUserAsync(driverId)
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(showDriver);
}
})
.</span><span style="background-color: yellow;">then</span><span style="background-color: #eeeeee;">(null, errorHandler);
}
</span></code></pre>
<br />
You can see that for all but one, all then statements are nicely aligned. This can be done since we return the actual asynchronous call from the callback.<br />
<br />
The reason I don't use this trick with GetUserAsync, is that, if I were to do that, I would jump out of the for loop that's processing each driver and only the first driver would be shown on the map.<br />
<br />
The last then statement is special as well, since it defines a global error handler. Whatever error occurs in whatever callback, this error handler will catch it. Another useful trick.<br />
<br />
I also extended this method a bit and actually caught the asynchronous calls in a variable, I called cancellable. Cancellation in JavaScript as well is done a bit differently. Once you define a global variable like this, you can call cancel on it.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function cancelHike() {
if (cancellable != null) {
cancellable.cancel();
var errorDiv = document.getElementById("errorText");
errorDiv.innerText = "operation cancelled";
}
}
</code></pre>
<br />
With this you have more or less the exact same application as I showed in the C# examples. But I do have to say I did need to alter some things in the RestCaller to get all this working for JavaScript. That is something I'll show you in the next (and last) blog post.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-5323594451345961872012-05-17T08:11:00.000-07:002012-05-17T09:25:05.061-07:00Async V: void methodsIn the <a href="http://proq.blogspot.com/2012/05/async-iv-progress-reporting.html">previous post</a> on async, I told you, we would go a bit deeper into void methods, since they behave differently than methods returning a Task or Task<t>. The difference is that, where non-void returning methods give you callback behavior, void methods give you fire and forget behavior. This can give you confusing results if you don't know how to spot and use them.<br />
<br />
Let's take a look again at our OnNavigatedTo method.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await _restCaller.PublishHikeRequest();
var driverIds = await _restCaller.GetDrivers();
if (driverIds != null)
await ShowDriversOnMap(driverIds);
var hikerIds = await _restCaller.GetHikers();
if (hikerIds != null)
await ShowHikersOnMap(hikerIds);
}
</code></pre>
<br />
Now, the original version of this code looked a bit different, I actually altered it to get the entire explanation on async right for you. The original version was actually written as follows:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await _restCaller.PublishHikeRequest();
var driverIds = await _restCaller.GetDrivers();
if (driverIds != null)
ShowDriversOnMap(driverIds);
var hikerIds = await _restCaller.GetHikers();
if (hikerIds != null)
ShowHikersOnMap(hikerIds);
}
</code></pre>
<br />
The difference here is that I didn't use await on the calls to ShowDriversOnMap and ShowHikersOnMap. The reason for this is that while writing this code, I had made these two methods void. You are not allowed to use the await keyword on a void method.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>private async void ShowDriversOnMap(List<Guid> driverIds)
{
foreach (var driverId in driverIds)
{
var driver = await _restCaller.GetUser(driverId);
var pushpin = new Pushpin();
pushpin.Text = "D";
pushpin.Tapped += async (s, args) =>
{
MessageDialog dialog =
new MessageDialog(string.Format("This is {0}.", driver.FullName));
await dialog.ShowAsync();
MessageDialog secondDialog =
new MessageDialog("I am shown only after the previous dialog finishes.");
await secondDialog.ShowAsync();
};
MapLayer.SetPosition(pushpin,
new Location(driver.LatitudeFrom, driver.LongitudeFrom));
MyMap.Children.Add(pushpin);
}
}
</code></pre>
<br />
The usage of void for these methods makes very much sense to me. You are just showing something on a UI, no need for these two methods to return anything, right? Well, indeed, right, but what I didn't expect was that the behavior of these void methods was completely different from the Task returning methods. That is, void methods behave as fire and forget methods. You can't even use await on them, that is why those keywords when calling these methods are missing, not because I forgot them, but because you're not even allowed to use them. Your compiler will complain if you do.<br />
<br />
The behavior you get in this case, is that, while the drivers are being shown on the map, since this call is fire and forget, the processing already continues with fetching all the hikers and showing those on the map as well. So you actually get parallel behavior and not callback behavior. In the case of showing the drivers and hikers on the map simultaneously, this might not seem such a big of a problem, but I can imagine cases in which it does present a problem.<br />
<br />
What is even a bigger problem is that for void methods you don't even have a clue that you are calling an async method. With Task and Task<T> returning methods you get a nice tooltip that says you are using an awaitable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd8_Ds2aB_TPxS97cohvamLEoHjmIBv2X3JEFSGP6iir24F3WBxKH28FIWmk36012XMNYM44lbkA6I80Jc-Lv6ikfDf1TZbV7kkgf_mb64PwD-UPMyicsGUcFxAEiTMf_ikYerIzZ2WOU/s1600/awaitable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="75" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd8_Ds2aB_TPxS97cohvamLEoHjmIBv2X3JEFSGP6iir24F3WBxKH28FIWmk36012XMNYM44lbkA6I80Jc-Lv6ikfDf1TZbV7kkgf_mb64PwD-UPMyicsGUcFxAEiTMf_ikYerIzZ2WOU/s400/awaitable.png" width="400" /></a></div>
<br />
With void returning async methods, you get none of this. The tooltip just says it's a void method, you have no clue of the fire and forget behavior.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXsys4jTSKQw331z7AhVbSeXCl5ZfVYbiQ9fURkaZWMIJyqovhTN6E3DXNkZRQXUi9YXMsrRKV_XJevkMgYaLKkdjvZwY-mcQsnLAVlYoFH1xGG8JP8_0KFKu0HOLgPyNDJD3hv6CvZs/s1600/void.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXsys4jTSKQw331z7AhVbSeXCl5ZfVYbiQ9fURkaZWMIJyqovhTN6E3DXNkZRQXUi9YXMsrRKV_XJevkMgYaLKkdjvZwY-mcQsnLAVlYoFH1xGG8JP8_0KFKu0HOLgPyNDJD3hv6CvZs/s400/void.png" width="400" /></a></div>
<br />
That is why, as far as async goes, it is recommended you always use Task or Task<T> returning methods, these ones give you callback behavior. The void returning methods are recommended for use only on event handlers.<br />
<br />
If using Task returning methods, you can also get parallel behavior. For this, you can use the WhenAll method on the Task class.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await _restCaller.PublishHikeRequest();
var driverIds = await _restCaller.GetDrivers();
var hikerIds = await _restCaller.GetHikers();
var showDriversTask = ShowDriversOnMap(driverIds);
var showHikersTask = ShowHikersOnMap(hikerIds);
Task.WhenAll(showDriversTask, showHikersTask);
}
</code></pre>
<br />
Both tasks will be executed in parallel and execution of the rest of the method will continue when both tasks are finished. Another handy method on the Task class is the WhenAny method. It behaves more or less the same as WhenAll, but it continues with the rest of the method body as soon as one of tasks you give it as a parameter finishes.<br />
<br />
Next post we will look at using async methods from JavaScript in WinRT.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-81846511670389530892012-05-04T02:44:00.000-07:002012-05-17T08:11:50.041-07:00Async IV: Progress ReportingIn the <a href="http://proq.blogspot.com/2012/05/async-iii-cancellation.html">previous post</a>, I already told you that progress reporting for asynchronous calls can be done by using the IProgress interface. This interface has a Report method with which you can report progress. You probably already saw me using the IProgress interface in the previous post, but now let's explain what actually happens.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
cts = new CancellationTokenSource();
try
{
await _restCaller.PublishHikeRequest(cts.Token);
var driverIds = await _restCaller.GetDrivers(cts.Token);
if (driverIds != null)
await ShowDriversOnMap(driverIds, cts.Token,
</span><span style="background-color: yellow;">new Progress<int>(p => statusText.Text = string.Format("{0} of {1}", p, driverIds.Count))</span><span style="background-color: #eeeeee;">);
var hikerIds = await _restCaller.GetHikers(cts.Token);
if (hikerIds != null)
await ShowHikersOnMap(hikerIds, cts.Token);
}
catch (OperationCanceledException exc)
{
statusText.Text = exc.Message;
}
}
</span></code></pre>
<br />
The Progress class is an implementation of the IProgress interface. The integer generic type parameter I send along is the type of progress I want reported. In this case I just want an integer value, but you can even have progress reported in a type you have specially defined for this purpous. The constructor of the Progress class takes in a lambda expression for the progress reporting. In this case I just show the number of drivers already shown on the map in the text of a TextBox.<br />
<br />
The reporting of progress itself is done in the ShowDriversOnMap method.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">private async Task ShowDriversOnMap(List<Guid> driverIds, CancellationToken token = default(CancellationToken), </span><span style="background-color: yellow;">IProgress<int> progress = default(IProgress<int>)</span><span style="background-color: #eeeeee;">)
{
var count = 0;
foreach (var driverId in driverIds)
{
if (</span><span style="background-color: yellow;">progress != null</span><span style="background-color: #eeeeee;"> && count % 10 == 0)
</span><span style="background-color: yellow;">progress.Report(count);</span><span style="background-color: #eeeeee;">
var driver = await _restCaller.GetUser(driverId, token);
var pushpin = new Pushpin();
pushpin.Text = "D";
pushpin.Foreground = new SolidColorBrush(Colors.Green);
pushpin.Tapped += async (s, args) =>
{
MessageDialog dialog = new MessageDialog(string.Format("This is {0}.", driver.FullName));
await dialog.ShowAsync();
};
MapLayer.SetPosition(pushpin, new Location(driver.LatitudeFrom, driver.LongitudeFrom));
MyMap.Children.Add(pushpin);
count++;
}
}
</span></code></pre>
<br />
I report progress in steps of 10. Since the IProgress in this case takes an int generic type parameter, I just send along an integer value to the Report method.<br />
<br />
With the techniques you've seen so far (basics, exception handling, cancellation and progress reporting), you can get started with using async. In the next posts we will go some steps further, though, we will look at what <a href="http://proq.blogspot.com/2012/05/async-v-void-methods.html">void asynchronous methods</a> do and start using async calls from JavaScript code. For this we will also create a WinMD library, which changes some things, both for defining asynchronous methods as for using them.<br />
<br />
But before you move on to that, let me first give you a couple of pointers to watch out for.<br />
<br />
Using the asynchronous features is made extremely easy for you. This implies that often you use them, without really thinking about what you are actually doing (hey, you're defining a callback, remember). I have found that once you start using async, you really need to think about how your users will be using your application. This implies thinking about cancellation, so you don't keep processing unnecessary calls.<br />
<br />
Also, at the end of the day you end up with quite some async methods in your code. Since every time you use await, you need to make your method async. And whatever calls you method, must use await and be made async as well, and so on.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-15500454588926117772012-05-03T02:55:00.003-07:002012-05-07T08:04:00.806-07:00Async III: CancellationThe previous posts in this series talked about the <a href="http://proq.blogspot.com/2012/04/async-i-basics.html">basics of async</a> and <a href="http://proq.blogspot.com/2012/05/async-ii-exception-handling.html">exception handling</a>. In this post we will take a look at cancellation and the beginnings of progress reporting.<br />
<br />
For cancellation you can make use of a CancellationToken. This is an extra parameter that can be send to an asynchronous method call, most asynchronous methods you find in the .NET framework provide an overload with cancellation. You can extend your own asynchronous methods as well to take in a CancellationToken.<br />
<br />
For progress reporting the IProgress interface can be used. This interface defines a Report method that can be used to report progress from within an asynchronous method. Asynchronous calls again can define overloads that take in a IProgress interface.<br />
<br />
Let's first take a look at cancellation.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">protected async override void OnNavigatedTo(NavigationEventArgs e)
{
</span><span style="background-color: yellow;">cts = new CancellationTokenSource();</span><span style="background-color: #eeeeee;">
try
{
await _restCaller.PublishHikeRequest(</span><span style="background-color: yellow;">cts.Token</span><span style="background-color: #eeeeee;">);
var driverIds = await _restCaller.GetDrivers(</span><span style="background-color: yellow;">cts.Token</span><span style="background-color: #eeeeee;">);
if (driverIds != null)
await ShowDriversOnMap(driverIds, </span><span style="background-color: yellow;">cts.Token</span><span style="background-color: #eeeeee;">,
new Progress<int>(p => statusText.Text = string.Format("{0} of {1}", p, driverIds.Count)));
var hikerIds = await _restCaller.GetHikers(</span><span style="background-color: yellow;">cts.Token</span><span style="background-color: #eeeeee;">);
if (hikerIds != null)
await ShowHikersOnMap(hikerIds, </span><span style="background-color: yellow;">cts.Token</span><span style="background-color: #eeeeee;">);
}
</span><span style="background-color: yellow;">catch (OperationCanceledException exc)</span><span style="background-color: #eeeeee;">
{
statusText.Text = exc.Message;
}
}
</span></code></pre>
<br />
As you can see, I added a datamember cts of type CancellationTokenSource to my class. A CancellationTokenSource gives you a CancellationToken through its Token property. This token can be send along to all you asynchronous methods. Once the operation gets cancelled, each asynchronous method using the token will be notified of cancellation. The result of cancellation will be an OperationCanceledException that you can catch.<br />
<br />
Cancelling an operation is as simple as calling Cancel on the CancellationTokenSource.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">protected void Cancel_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
try
{
</span><span style="background-color: yellow;">cts.Cancel();</span><span style="background-color: #eeeeee;">
}
catch (AggregateException exc)
{
exc.Handle((ex) => {
return true;
});
}
}
}
</span></code></pre>
<br />
The AggregateException I catch here, is necessary since the REST calls in the RestCaller class tend to throw additional exceptions on cancellation (this only happens occasionally). I just swallow these kinds of exceptions, since they don't add any important information.<br />
<br />
The nice thing about cancellation is that you can have it bubble down in your code. I create the CancellationToken in the top layer of my appllication, but it's send along to different methods, which again can send it to other asynchronous methods they call. For instance the GetDrivers method sends it along with its asynchronous REST call.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">public async Task<List<Guid>> GetDrivers(</span><span style="background-color: yellow;">CancellationToken token = default(CancellationToken</span><span style="background-color: #eeeeee;">))
{
List<Guid> drivers = null;
try
{
var client = new HttpClient();
var request = new HttpRequestMessage();
request.Headers.Add("Accept", MESSAGE_TYPE);
request.RequestUri = new Uri(string.Format("{0}/Hiker/{1}/DriverIdsNearby", BASE_URL, MY_ID));
var response = await client.SendAsync(request, </span><span style="background-color: yellow;">token</span><span style="background-color: #eeeeee;">);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
drivers = await JsonConvert.DeserializeObjectAsync<List<Guid>>(content);
}
catch (HttpRequestException exc)
{
var dialog = new MessageDialog(exc.Message);
dialog.ShowAsync();
}
return drivers;
}
</span></code></pre>
<br />
This makes it very easy to cancel something. Whatever your code is executing at the moment, it gets cancelled.<br />
<br />
In the <a href="http://proq.blogspot.com/2012/05/async-iv-progress-reporting.html">next post</a> we will look at progress reporting.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-86613464964567689942012-05-02T04:08:00.000-07:002012-05-17T07:27:45.590-07:00Async II: Exception HandlingIn the <a href="http://bit.ly/InaDXT">previous blog post</a>, we looked at the basics of async. In this post, we will look at exception handling. You need exception handling the moment something goes wrong in an asynchronous call. When this happens, the Task that comes out of the asynchronous call will have an error status and you won't be able to get the result from the method.<br />
<br />
Handling these kinds of error situations is actually really simple. The only thing you need to do is wrap your asynchronous call in a try - catch statement, just like you would do with synchronous code. Let's take a look at an example:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>public async Task PublishHikeRequest()
{
var hikeRequest = GetHikeRequest();
try
{
var client = new HttpClient();
var url = string.Format("{0}/HikeRequest", BASE_URL);
var response = await client.PostAsync(url, await BuildJsonContent(hikeRequest));
response.EnsureSuccessStatusCode();
}
catch (Exception exc)
{
var dialog = new MessageDialog(exc.Message);
dialog.ShowAsync();
}
}
</code></pre>
<br />
This method can be found in the RestCaller class, the one that's being used in the OnNavigatedTo from the previous blog post. In this method we post a message to a REST service in an asynchronous way. There are a couple of points where this code can give us error situations. The REST service can be down or for some reason our Json message can't be build as expected. For this we use a try catch clause to wrap the asynchronous calls.<br />
<br />
Simpler than this, they can't make it for you. I just want to point out one more thing. Don't do as I did and show a MessageDialog in your catch clause. I just put it there for demoing purposes, but it can really bite you in the butt. Let me explain: If the REST service is down, it will take a while for the timeout of the call, giving a HttpRequestException, to kick in (this is about one minute). By this time, it is very well possible that the user of your application has already performed 10 other actions. The MessageDialog will only get him confused, because it's a reaction to an action he performed a minute ago. For this it is important that you know how to cancel actions that were kicked off, but are no longer relevant in the current user context.<br />
<br />
That is why, in the <a href="http://proq.blogspot.com/2012/05/async-iii-cancellation.html">next blog post</a>, we will look at cancellation (and progress reporting).<br />
<br />
And just another small thought on asynchronous calls I want to add. After the Visug session I got a question asking if you don't need to keep track of your background threads and if in the PublishHikeRequest method I can do stuff with my UI (for instance alter text in a TextBox). The answer is: yes you can. Your code actually executes synchronously until you get an await. This means all code in PublishHikeRequest is synchronous up until the PostAsync call. This is a framework call that actually does some stuff with threadpools or async I/O. But we don't need to worry about that. All of our code is still synchronous. And the callback that is being build for us, with the rest of our message body, will again be called on the UI thread. So, to sum up, nothing to worry about, go ahead and alter the text of that TextBox.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-47699363019976859212012-04-30T01:51:00.001-07:002012-05-17T07:27:25.350-07:00Async I: The BasicsIn the recent talk I gave for <a href="http://www.visug.be/">Visug</a>, we looked at the new async capabilities in the next version of the .NET Framework. The slides of this session can be found <a href="http://www.slideshare.net/Qframe/visug-async">here</a>. In this series of posts, I would like to walk you through the different demo's I showed during this talk.<br />
<br />
The demo's were actually a rewrite of an existing application, the Blitzhiker application, we've developed for Windows Phone. The rewrite is a port of this application to the Windows 8 runtime.<br />
<br />
The Blitzhiker application itself tries to bring hikers (people looking for a ride) and drivers (people with a car) closer together.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL_Qfy4Imf5NvqjL4Zcs9DBDTxV3w48CmxbqgICPfUjt9ee9EuxMB-unAb7ubee8Ol-OkpFRE5WWkvsaATqZaDw4Gh0TNkO4fKS0igp5eRDwHKFQkwz1oXjgC7wF6T8qPIPAyhb2IWlAs/s1600/StartScreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL_Qfy4Imf5NvqjL4Zcs9DBDTxV3w48CmxbqgICPfUjt9ee9EuxMB-unAb7ubee8Ol-OkpFRE5WWkvsaATqZaDw4Gh0TNkO4fKS0igp5eRDwHKFQkwz1oXjgC7wF6T8qPIPAyhb2IWlAs/s320/StartScreen.png" width="320" /></a></div>
<br />
Hikers can publish hikerequests and get an overview of drivers and other hikers nearby. Below you can see a screen shot after a hiker has published his request. A Bing map is shown with pushpins for each driver nearby. Since all calls are done asynchronously, the entire user interface stays responsive while pushpins are shown on the map.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3ycO6RZ7iS_tHrr0xirzoPwYnOvCSxw1_Re7GNXvEctf1cBDdG2_6FbpVYvqBP6pZW3WOkUn5eiGtzMDHsQV3uhoxM1fVJUx2_G0uy3gHwcihEa9MzHVCrAhBNGY6vwqhBHkhDh_AhVY/s1600/Publish.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3ycO6RZ7iS_tHrr0xirzoPwYnOvCSxw1_Re7GNXvEctf1cBDdG2_6FbpVYvqBP6pZW3WOkUn5eiGtzMDHsQV3uhoxM1fVJUx2_G0uy3gHwcihEa9MzHVCrAhBNGY6vwqhBHkhDh_AhVY/s400/Publish.png" width="400" /></a></div>
<br />
<br />
First thing we will take a look at, is the basics of asynchronous calls. What makes up an asynchronous call and how does it affect the execution of your program.<br />
<br />
The code to publish the hikerequest, show the drivers on the map and after that show the hikers on the map, looks like this:<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">protected </span><span style="background-color: yellow;">async</span><span style="background-color: #eeeeee;"> override void OnNavigatedTo(NavigationEventArgs e)
{
</span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> _restCaller.PublishHikeRequest();
var driverIds = </span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> _restCaller.GetDrivers();
if (driverIds != null)
</span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> ShowDriversOnMap(driverIds);
var hikerIds = </span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> _restCaller.GetHikers();
if (hikerIds != null)
</span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> ShowHikersOnMap(hikerIds);
}
</span></code></pre>
<br />
What happens is that we publish a hikerequest, after that, ask for all of the drivers on our route, next, show these guys on our map, then, get all of the hikers near us and show these on the map as well. The ShowDriversOnMap is a call that usually takes some time when there are a lot of drivers nearby. What we notice though is, that while showing the drivers, the entire application stays responsive, which is actually what we want from asynchronous calls.<br />
<br />
You can spot the use of several awaits in the OnNavigatedTo method. What happens is that an await kicks of the execution of an asynchronous method and turns the rest of your method body into a callback. So in this piece of code several callbacks will be created at compile time, without you needing to mess up your code for this, you can keep on writing as if you are writing synchronous code.<br />
<br />
What is also interesting about awaiting code this way, is that each callback will be executed in the same execution context that kicked of the asynchronous call. So, if you were on a UI thread, your callback will be executed on the UI thread. No need for Dispatcher.Invoke!<br />
<br />
You probably noticed as well the use of the async keyword. This tells the compiler that the current method contains asynchronous calls and that there will probably need to be some extra compiler effort to create the necessary callbacks. Once you use the await keyword in a method, you need to put the async keyword in the method header. If you don't, your code won't compile. An async method can either have a void return type (as is the case in our piece of code) or can have a Task or Task<T> return type. Let's take a look at the ShowDriversOnMap method, which has a Task return type.<br />
<br />
<pre style="border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code><span style="background-color: #eeeeee;">private </span><span style="background-color: yellow;">async</span><span style="background-color: #eeeeee;"> Task ShowDriversOnMap(List&lt;Guid> driverIds)
{
foreach (var driverId in driverIds)
{
var driver = </span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> _restCaller.GetUser(driverId);
var pushpin = new Pushpin();
pushpin.Text = "D";
pushpin.Tapped += </span><span style="background-color: yellow;">async</span><span style="background-color: #eeeeee;"> (s, args) =>
{
MessageDialog dialog =
new MessageDialog(string.Format("This is {0}.", driver.FullName));
</span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> dialog.ShowAsync();
MessageDialog secondDialog =
new MessageDialog("I am shown only after the previous dialog finishes.");
</span><span style="background-color: yellow;">await</span><span style="background-color: #eeeeee;"> secondDialog.ShowAsync();
};
MapLayer.SetPosition(pushpin,
new Location(driver.LatitudeFrom, driver.LongitudeFrom));
MyMap.Children.Add(pushpin);
}
}
</span></code></pre>
<br />
Again the await keyword is used, kicking of an asynchronous method and automatically turning the rest of the method body into a callback. You can also spot the use of the await keyword inside of a lambda expression. In WinRT there is no more DialogBox, but a MessageDialog. This one doesn't have a Show method, but a ShowAsync method, so, again, you can use await on this. Once you do this, you need to mark the lambda expression with the async keyword as well. I actually show 2 MessageDialogs with an await keyword. If you would set breakpoints in this lambda, you would spot the first dialog being shown and your code not starting to create the second dialog until you close the first one. That's the callback kicking in.<br />
<br />
That's it for the basics of asynchronous calls. In a <a href="http://proq.blogspot.com/2012/05/async-ii-exception-handling.html">next post</a>, we will go into exception handling and take a look at the RestCaller class that is being used in the code examples of this blog post.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-45500447353359500782012-04-13T02:03:00.000-07:002012-04-13T02:03:13.770-07:00JSON POST with ASP .NET Web APII have been struggling a bit with porting existing Json calls to the new <a href="http://www.asp.net/web-api/overview">ASP .NET Web API</a> framework. I actually got the GET request working pretty quickly, but it were the POST (and DELETE en PUT) requests that were giving me headaches. Problem is the current brevity and lack of practical examples for the Web API framework. So here goes a short example of getting a Json POST up and running.<br />
<br />
For these examples I used the Visual Studio 2011 beta version.<br />
<br />
Let's first start with the GET request. What you need for this is the HttpClient class, which can be found in the System.Net.Http namespace. This class provides methods like GetAsync, PutAsync, DeleteAsync and PostAsync. The 'Async' extensions let you know that you can use the new async and await keywords to get this up and running. A GET requests with the HttpClient consists of only two lines of code.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>var client = new HttpClient();
var response = await client.GetAsync("http://some_url/resource_name/resource_id");
response.EnsureSuccessStatusCode();
</code></pre>
<br />
All of this is contained in a method that has the extra async keyword. I also added the EnsureSuccessStatusCode call to verify my call to the REST service didn't fail. If the call fails the EnsureSuccessStatusCode will throw an exception. So you can easily wrap this piece of code in a try catch block.<br />
<br />
So, that was quite easy. The GET call should work immediately.<br />
<br />
On to the POST call. I actually want to post an object to our REST service. The previous version of the code I was porting to the Web API used the <a href="http://restsharp.org/">RestSharp</a> (performs REST calls) and <a href="http://newtonsoft.json/">NewtonSoft.Json</a> (serializes from and to Json) frameworks to perform REST calls (both are available via NuGet). I started out reusing only NewtonSoft.Json, since the HttpClient class removes the need for the RestSharp framework. But is turned out I couldn't get the serialized Json object send to the service in a acceptable format. The service kept giving me 400 Bad Request messages. So I was doing something wrong.<br />
<br />
After some searching I found there are a couple of different content class types you can use when performing a PostAsync. I used StringContent up untill then, but I needed a ObjectContent. The HttpRequestMessage class can create one for you. Moreover, the Web API contains its own Json formatters, so the need for the NewtonSoft library became obsolete.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>var anObject = new MyObjectType
{
SomeProperty = "some value"
};
try
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestMessage = new HttpRequestMessage();
var content = requestMessage.CreateContent&lt;MyObjectType>(
anObject,
MediaTypeHeaderValue.Parse("application/json"),
new MediaTypeFormatter[] { new JsonMediaTypeFormatter() },
new FormatterSelector());
var response = await client.PostAsync("http://some_url/resource_name", content);
response.EnsureSuccessStatusCode();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
</code></pre>
<br />
And there you have it, my first successful Json POST message.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com3tag:blogger.com,1999:blog-4315928131887373364.post-46404809810815126472012-03-04T02:42:00.000-08:002012-03-04T02:48:05.951-08:00Adding navigation to WinRT JavaScriptIn the <a href="http://proq.blogspot.com/2012/03/navigating-with-winrt-javascript.html">previous post</a> we looked at the anatomy of a basic WinRT JavaScript navigation application. In this post we will add 2 additional pages and navigate between them. I will use the same fragment navigation as used in default.html and homePage.html.<br />
<br />
First thing I'll do - just to spare me some typing work - is make two copies of homePage.html and call these page2.html and page3.html. Next, I'll alter the default content of homePage.html (there where it says 'content goes here') and replace it with two link tags. I'll add the same content to page2 and 3 as well, so as to easily navigate between all three pages.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><section role="main" aria-label="Main content">
<p>
<div>Navigate to: &lt;/div>
<div>
<a href="page2.html">Page 2</a>
<a href="page3.html">Page 3</a>
</div>
</p>
</section>
</code></pre>
<br />
When you try this out, you can actually navigate to page2 and 3. That wasn't too hard to do, now was it. Only downside with this app is, that the back button is not functioning (it stays disabled both on page2 and page3). The appbar as well is not popping up when you click your right mouse button. Also, when you look at it, the contents of pages 2 and 3 are not shown right, they are shown too far to the left. Obviously we need to add some extra code to fix all this.<br />
<br />
So I started to play around with this little application, to see what could be done to get it functioning correctly. First thing I did, was add some breakpoints to the default.js file's navigated function. This showed me that, when clicking the page2 or page3 link, the navigated event was not being hit. Apparently, using a simple a tag with an href attribute doesn't trigger navigation. This had to be done some other way then.<br />
<br />
For this I added some extra code to the homePage.js file.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function fragmentLoad(elements, options) {
WinJS.UI.processAll(elements)
.then(function () {
// TODO: Initialize the fragment here.
var page2Nav = document.getElementById('page2Nav');
if (page2Nav) {
page2Nav.addEventListener('click', function () {
WinJS.Navigation.navigate('/html/page2.html');
}, false);
}
});
}
</code></pre>
<br />
The fragmentLoad function is called when the homePage gets loaded. When this happens, we get hold of the page2Nav element (I added an id to the link element). If we find this element, we add an eventlistener for its click event. When clicked, we should navigate to page2.html. A similar piece of code can be added to navigate to page3.<br />
<br />
After adding this, you will notice that after you click the page2 link, the navigated event in default.js is being hit. That's what we wanted. But wait, as it gets hit, the application doesn't find our back button, its value stays null. That's not right, it should be able to find the back button.<br />
<br />
The thing that's wrong here is the fact I added an href to my a tags. If you remove this and let WinJS just handle all of the navigation, you will see the back button is being found. Now, if you land on page2, the back button can be used to navigate back to the homePage. Even the appbar is functioning as expected.<br />
<br />
As cool as this is (hey, I can navigate), the downside of using these techniques is that you get an awfully big buy-in into the WinRT way of building apps. When you choose to develop your applications with HTML5 and JavaScript, I think one of the reasons for your choice is portability, the fact that you can take this same code and run it on a different machine with minimal effort. That is why you should think twice when using WinRT functionality. Or, you'd better start writing wrappers for platform specific libraries. But than still ... Hey, I can navigate.Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0tag:blogger.com,1999:blog-4315928131887373364.post-67228110789515086622012-03-03T01:01:00.001-08:002012-03-04T02:47:05.124-08:00Navigating with WinRT JavaScriptI am currently playing around with WinRT JavaScript applications. Starting out with a navigation application written from scratch, just to find out how it all fits together. The MSDN library is actually quite scarce when it comes to resources on WinRT. They give you the overall picture of how Metro style apps work, but, for JavaScript applications, the actual information is a bit meager. So I thought it would be nice to dissect a Metro style navigation app and see what code you need to get it up and running. Also beware that the information I will be giving here is based on the first developer preview of Windows 8 and Visual Studio 2011 Express Edition. Things are still very likely to change in the next couple of months.<br />
<br />
What I did, was create two Metro style JavaScript applications, one based on a blank project template and one based on the navigation application project template. Let's first see what the navigation application gives us.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjvEDxSEmfc7BNnc9d7khmV_RELyU2A1VmHJ6FVxySao4Jn-HiiksRblTDyBcY_FerRyzQXDaivZw5F9JQZ1aQpkFRpopecOUSpdFlBeavhCXAlpuEkyCSOxAvyK-i8bpJLW845fyVWl4/s1600/project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjvEDxSEmfc7BNnc9d7khmV_RELyU2A1VmHJ6FVxySao4Jn-HiiksRblTDyBcY_FerRyzQXDaivZw5F9JQZ1aQpkFRpopecOUSpdFlBeavhCXAlpuEkyCSOxAvyK-i8bpJLW845fyVWl4/s400/project.png" width="192" /></a></div>
<br />
<br />
When you look at the project of the navigation application, you will see it gives you a couple of predefined html, JavaScript and css files. There are two html files present, a default.html and a homepage.html file. First let's take a look at the homepage.html file. In the head section it includes the JavaScript files you find in the solution, so nothing new or fancy there. In the body there is a div defined with content.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><!-- The content that will be loaded and displayed. -->
<div class="fragment homePage">
<header role="banner" aria-label="Header content">
<button disabled class="win-backbutton" aria-label="Back">&lt;/button>
<div class="titleArea">
<h1 class="pageTitle win-title">Welcome to NavApp!&lt;/h1>
</div>
</header>
<section role="main" aria-label="Main content">
<p>Content goes here.&lt;/p>
</section>
</div>
</code></pre>
<br />
The main div has a couple of classes defined on it, fragment and homePage. The fragment class we will come back to later on, when we take a look at the JavaScript files of the project. Just remember that it's there on the main div of the homepage.<br />
<br />
Within the main div there is a header tag defined. This shows that WinRT JavaScript applications make use of new HTML5 features. The header tag has a role attribute, with a value of banner. There is also a role defined on the section tag a bit further down the homepage, with a value of main. These role attributes are primarily used as selectors in the css and JavaScript files. There is no real functionality associated with them.<br />
<br />
The last peculiar attribute values can be found on the button and the h1 tags. Their classes are set to win-backbutton and to win-title respectively. With WinRT JavaScript applications you will find there are a lot of these win-something attribute values. You would think these give you out of the box functionality. Well, they don't. You will find that all magic is really just JavaScript doing it's thing. Those win-something attributes again, are just selectors for the css and JavaScript files. When you run the appication, you will see that the win-backbutton is actually an arrow with a circle around it. That's just plain css:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>.win-backbutton::before
{
font-family: "Segoe UI Symbol";
content: "\E0D5";
vertical-align: 50%;
}
</code></pre>
<br />
So, let's take a look at the default.html page. The header again is just JavaScript and css file includes. The body is more interesting.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><body data-homePage="/html/homePage.html">
<div id="contentHost">&lt;/div>
<div id="appbar" data-win-control="WinJS.UI.AppBar" aria-label="Command Bar" data-win-options="{position:'bottom', transient:true, autoHide:0, lightDismiss:false}">
<div class="win-left">
<button id="home" class="win-command">
<span class="win-commandicon win-large">&#xE10F;&lt;/span>&lt;span class="win-label">Home&lt;/span>
</button>
</div>
</div>
</body>
</code></pre>
<br />
There is a data-homePage attribute on the body tag and it is set to our homePage.htm file. You will also find a contentHost and appbar div. The contentHost makes you suspect that the default.html page is actually the start page of your application and that other html pages will actually be loaded as fragment into it. That is indeed the case here. But then, why, as you run the application, don't I see the appbar that is defined at the bottom. You do get to see all the content of the homePage, but the appbar is nowhere in site. The reason is that, to see the appbar, you need to swipe up, or, if that doesn't work on your device, perform a right mouse click. There's the appbar for you.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPmBFc12-YvjdDeNccci632HWPonEDmbM2pHLFixtL_HP147St8LYMQwDJvilTMU8SgNc5RbiLDPidg2SqMKN14BRIobjXEFmnlakx2r45QWfWCQJBE0ECRFDbxImn9GYjIQPpcMLe39k/s1600/appbar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPmBFc12-YvjdDeNccci632HWPonEDmbM2pHLFixtL_HP147St8LYMQwDJvilTMU8SgNc5RbiLDPidg2SqMKN14BRIobjXEFmnlakx2r45QWfWCQJBE0ECRFDbxImn9GYjIQPpcMLe39k/s320/appbar.png" width="320" /></a></div>
<br />
So, where does all the magic happen? In the JavaScript files of course. Let's first take a look at the default.js file. There are a couple of functions defined here. Let's not start at the top, but at the bottom.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>WinJS.Navigation.addEventListener('navigated', navigated);
WinJS.Application.start();
</code></pre>
<br />
An eventlistener for the navigated event gets added and the application is started. That's simple, right. Right above these two statements we find the handler for activating the mainwindow.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>WinJS.Application.onmainwindowactivated = function (e) {
if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
homePage = document.body.getAttribute('data-homePage');
document.body.addEventListener('keyup', function (e) {
if (e.altKey) {
if (e.keyCode === WinJS.Utilities.Key.leftArrow) {
WinJS.Navigation.back();
}
else if (e.keyCode === WinJS.Utilities.Key.rightArrow) {
WinJS.Navigation.forward();
}
}
}, false);
WinJS.UI.process(document.getElementById('appbar'))
.then(function () {
document.getElementById('home').addEventListener('click', navigateHome, false);
});
WinJS.Navigation.navigate(homePage);
}
}
</code></pre>
<br />
This code says as much as, when we launch the application, do the following things:<br />
<ul>
<li>Our homepage is set to the attribute value of the data-homePage attribute of the body element.</li>
<li>If a user presses the alt key and the left or right button, navigate forward and backward. </li>
<li>Find the appbar and attach a click handler to the home element. The navigateHome function is defined at the top of the JavaScript file and contains pretty straightforward code.</li>
<li>And last, but not least, navigate to the homePage.</li>
</ul>
<div>
Right abobe this function, you will find another function definition. </div>
<div>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>function navigated(e) {
WinJS.UI.Fragments.clone(e.detail.location, e.detail.state)
.then(function (frag) {
var host = document.getElementById('contentHost');
host.innerHTML = '';
host.appendChild(frag);
document.body.focus();
var backButton = document.querySelector('header[role=banner] .win-backbutton');
if (backButton) {
backButton.addEventListener('click', function () {
WinJS.Navigation.back();
}, false);
if (WinJS.Navigation.canGoBack) {
backButton.removeAttribute('disabled');
}
else {
backButton.setAttribute('disabled', 'true');
}
}
WinJS.Application.queueEvent({ type: 'fragmentappended', location: e.detail.location, fragment: host, state: e.detail.state });
});
}
</code></pre>
</div>
<div>
<br />
This tells us what happens when we navigate (remember, the previous function actually navigated to the homePage, so this gets called at the start of the application).<br />
<br />
<ul>
<li>It clones the current fragment state (I am guessing this remembers where we are coming from and in what state the page is at the moment).</li>
<li>And, hey, next bit is some asynchrony. After the cloning is done, a function gets executed for the fragment.</li>
<li>It finds the contentHost on the default.html page and appends the fragment to it. There you have masterview (default.html)- detailview (homePage.html) behavior.</li>
<li>The backbutton also gets some extra functionality. Based on the fact whether we can go back or not, the button gets disabled or enabled and the click handlers get attached.</li>
<li>Last bit is queuing the fact that the fragment got appended, so the WinRT runtime can do its thing.</li>
</ul>
<div>
On the one hand, that's all simple JavaScript code. On the other hand, if you are used to working with the regular .NET languages, this seems like quite some code you need to write for some basic functionality. </div>
<div>
<br /></div>
<div>
Let's find out, in a next post, what we need to do to navigate to a new page in our application. </div>
</div>Gitte Vermeirenhttp://www.blogger.com/profile/15607673394249897025noreply@blogger.com0