Extending App Studio's Code as a Developer
Published on Tuesday, August 6, 2013 8:00:00 PM UTC in Programming & Tools
In my previous post I briefly talked about the possibility to download the generated code of your App Studio apps to extend it with your own ideas and customizations. There are already some posts showing up demonstrating how easy this is, for example this one by Joost van Schaik using Expression Blend and Visual Studio. As someone who likes clean code a lot, in this post I rather want to focus on the structure and technical details of the generated solutions, and give you a quick example of how to put that to good use.
A first look
When you download the source code of an app from the App Studio web site and take a first look at it in Visual Studio, you can see something quite striking:
Terms like Ioc, services and the overall nice abstraction of all important implementation details using interfaces is not something I was expecting from a generated code base and a tool that aims at simple apps for beginners or rapid prototyping. When you scroll down a little further you will see that this even applies to the view model level, using a locator mechanism and interfaces for all the involved view models.
Taking a bird's eyes view, when you look at the overall solution structure it becomes obvious that the code also is structured physically in multiple separate projects:
All this proves to be valuable when you want to extend the existing implementations or even completely replace some of the generated parts completely, because it minimizes the required changes in the existing code base. Remember, it's still generated code (and not yours), so every change you need to make first requires that you read and understand the existing implementation and then place your own code and changes correctly. With concepts like Ioc these changes can be performed a lot more surgically and hence with less effort and also a much cleaner coding style.
An example
Let's crack one of the existing service implementations open to see what it actually does: I'm using the IDialogService implementation as it is most simple (comments removed for clarity):
public class DialogService : IDialogService
{
public void Show(string message)
{
MessageBox.Show(message);
}
public void Show(string message, string caption)
{
MessageBox.Show(message, caption, MessageBoxButton.OK);
}
}
Now let's say we want to replace that with something a bit more fancy. Instead of using message boxes I want to make use of the more beautiful message prompts of the Coding4Fun toolkit. Luckily it is available on NuGet so I can pull it into the project easily without leaving Visual Studio:
Once this is done, I create a new class in the Windows Phone app project named "FancyDialogService" and place it next to the existing DialogService. The implementation is quite straight forward:
public class FancyDialogService : IDialogService
{
public void Show(string message)
{
var messagePrompt = new MessagePrompt();
messagePrompt.Message = message;
messagePrompt.Show();
}
public void Show(string message, string caption)
{
var messagePrompt = new MessagePrompt();
messagePrompt.Title = caption;
messagePrompt.Message = message;
messagePrompt.Show();
}
}
Now the last thing I need to do is get the application to use my new implementation instead of the old one. This is the only step where we actually need to put our hands on the existing code. To this end, I open up the IContainer implementation at Ioc/Container.cs. There I look for the registration of the existing dialog service in the constructor's code and replace it with my own:
public Container()
{
_currentContainer = new UnityContainer();
// [...]
// Peter Kuhn: changed the implementation here
//_currentContainer.RegisterType<IDialogService, DialogService>();
_currentContainer.RegisterType<IDialogService, FancyDialogService>();
// [...]
}
And that's it. From now on, the application will use a different dialog implementation wherever it is used in the software! That is one of the beautiful side effects of having a nice and clear code structure with isolated components and implementations.
Note: if you're not familiar with the concept of Ioc, a first start could be a quick read on Wikipedia, or taking the more sophisticated version by Martin Fowler that focuses on dependency injection, for example.
A word of truth
Of course I have picked the simplest possible sample in this post, and I won't lie to you. If you try to customize other parts of the app, for example the views, you will have to touch a lot more of the existing code base, and put more effort into it. And even in the places where Ioc and DI are used you may have unexpected trouble1.
But the point I wanted to demonstrate is the following: if you do a "File/New Project" today the best you can get out of current templates is a simple MVVM setup. It's extremly pleasing to see that more advanced techniques are finding their way into automated tooling now, and I hope that this trend will continue. It helps teaching devs the benefits right from the start and to make these details better known and understood by a larger audience – thanks for that!
Tags: App Studio · Clean Code · Ioc · Windows Phone