Tag Archives: C#

How much code can you really place in your Portable Library?

Recently, Jevgeni asked me how much code I was able to share between my projects by using a Portable Library. He is contemplating building a Windows Phone and a Windows Store app and wants to create a Portable Library for sharing common code.

So I decided to get some numbers based on my new app code which is going to (hopefully) reach Windows Store soon.

Code Sharing between a Portable Library and a Windows Store app

Code sharing between a Portable Library and a Windows Store app

The app is not 100% ready yet, so I might add few lines of code but at the moment it turns out I placed more than 70% of my code in a Portable Library.

However, I invested quite a lot into having such a structure as I plan to release a Windows Phone app around the same core.

While you are waiting for my new app to be released :), go ahead and try my other apps already in the Windows Store: Puzzle Frenzy (download link) and Puzzle Frenzy Kids (download link).

Ask for User Rating: The Story of How I Doubled My Daily App Downloads

I currently have two apps in the Windows Store: Puzzle Frenzy and Puzzle Frenzy Kids. I’ve been closely monitoring user rating, feedback and request from day one and tried at the same time to tweak and improve the apps.

However, one thing I noticed quite fast was that my app was not getting too many ratings. Even if rating an app is possible in Windows 8 for all apps without extra work (bring up right side bar -> Settings -> Rate and review), my users were simply not doing that. On top of that, I noticed that my competitors’ apps and all the top apps in the same category had hundreds, thousands, even tens of thousands of ratings.

I also realized that the more ratings an app has, the higher it is placed in the Windows Store. It goes without saying that user ratings have a significant contribution to the ranking of the app.

Therefore, I decided to ask for user rating inside the apps, to see if the users will respond and rate my apps more frequently.

However, I found what I think is the sweet spot for getting users to rate the app:

  • I will ask users to rate the app only after they have engaged in (and hopefully enjoyed) the app, that is after they already played 3 puzzle games. By doing so, the users will most likely give it a good rating because they appear to have enjoyed the app enough to stay in the app and play all the 3 games.
  • I offer the user the choice not to rate it and ask again later. I tried not to be too annoying with these requests so I only display it after 3, 7, 15 or 30 games. If even after the fifth prompt the user hasn’t rated the app, I won’t bother him again because he most likely isn’t going to rate the app anyway.
  • I don’t bother the user again once he rated the app, but I still display a “Rate app” button on the home page, in case he changes his mind or wants to update his rating.
Puzzle Frenzy User Rating Prompt

Puzzle Frenzy User Rating Prompt

After introducing these changes, the number of ratings I was getting increased quite a lot.  In around one week I started to get the same number of ratings which before I was getting in one month.

As a consequence, (there were other factors for sure, but the user rating prompt was most likely the most important) the apps got ranked higher and higher, and they started getting more downloads.

On average, now I get around twice as many downloads as I did before.

I highly recommend adding such prompt to anyone developing apps on any platform.

Be ready however, with more ratings and feedback comes more responsibility.

Take user feedback into account and react to it as it will help you improve your app.

Good luck!

Building Jigsaw Puzzle Frenzy: sharing code between WP and WinRT

When I first started working on Puzzle Frenzy I wanted to maintain both the original WP app and also to create a new WinRT app by reusing and sharing as much code as possible.

My plan was based on the presentations at Build which promised  which promised up to 70% code share between  WP and WinRT. In particular check out Create Cross-platform Apps using Portable Class Libraries.

During different stages of the project I tried several approaches for achieving this goal:

Share physical source files between WP and WinRT projects

I initially started building the WinRT app adding new projects to the solution containing the same files as the WP.

The problem

While a low of classes in the WP and WinRT are “identical” in functionality, they are often not in the same  namespace.  On top of that, using the same source files in more then one project is by itself problematic.

Direct consequences:

1.Trying to use the same source files for both WP and WinRT resulted in files like this one:

#if WINDOWS_PHONE
using System.Windows.Media;
#else
using Windows.UI.Xaml.Media;
#endif

Furthermore, for some special cases I was forced to have constructions like this one:

#if WINDOWS_PHONE
//Do something
#else
//Do something else
#endif

2.Having the physical same file referenced by two projects in Visual Studio is a lot of work. Whenever something breaks for one project (90% of the time due to a usings declaration change) the file containing the error has to be opened from the context of the failing project. If the file is opened in the other project the error won’t be highlighted in the code and the solution won’t compile.

For few files, this setup can be maintained even if it is inconvenient. However, as the file count grows, keeping up with the changes is a too complicated task.

Using Portable Libraries

For the appropriate scenarios Portable Libraries are awesome. It eliminates the need for duplicated files altogether as the library can be referenced by both the WP and WinRT. In my case however I wasn’t able to use them because I use Point and Size classes throughout my project. These classes are not available in Portable Libraries. I could have created my own implementation of Point and Size to overcome this limitation, but given the scale of the changes I preferred not to do it: a simple search reveals that I use these classes in more than 100 places in my code.

From what I’ve experienced so far, Portable Libraries offer limited classes to work with. My ViewModels layer which I was planning to keep there needs far to many things which are not available.

Conclusion

Sharing code between WP8 and WinRT can prove to be troublesome.

Both duplicate projects and Portable Libraries have limitations, making it in my case are quite challenging to use.

If sharing the code between the two apps is really your goal, I am fairly confident it can be achieved. However, in my case, for this particular app, attempting to share the code only slowed me down. In the end I kept using duplicated projects but I am not maintaining them at the same time.

I take turns in development cycles implementing features and adjusting the code to work on the other platform. While doing so I introduce bugs in the project not being maintained at the time, but the amount of work needed to fix it is far less than implementing new features at once on both platforms.

Closing argument

If you start developing a new app and want to target WP and WinRT consider using Portable Libraries from the start. It will have some limitations but will also force you to place the code in the right place in order to be shared.

If you already have an WP app and want to migrate it to WinRT you might want to start by maintaining duplicated projects in order to limit the size of the changes needed. Once you reach a stable state you can of course look into  moving towards Portable Libraries if code sharing is your goal.

Have a look and see how it turned out.

Jigsaw Puzzle Frenzy is available in Windows Store, check it out and tell me what you think: http://apps.microsoft.com/windows/en-GB/app/puzzle-frenzy/28238e98-ac0f-4a6b-81ea-a31a24a15acf.

You can also give your feedback on app’s review page or on app’s Facebook page http://www.facebook.com/PuzzleFrenzyApp.

Happy codding!

Puzzle Frenzy home page

Building Puzzle Frenzy: using small source code files

As I told you before, Puzzle Frenzy was build starting from an old app I wrote for WP7. A lot of things changed since then, and most importantly I got to read Uncle Bob’s Clean Code as well as watch some of his Clean Code episodes.

Based on what I learned by reading the book I started refactoring the code. One of the thing that bothered me the most in the old code was the big source files, where I kept big classes and long methods.

Over time I managed to decrease the classes size quite a lot which helps me when it comes to testing, fixing bugs or adding new features.

Here is a comparison of the file size numbers:

Before After
Total line count 4114 6514
Source files count 45 118
Average file line count 91 55

meaning that

  • I increased the total amount of code with 58%
  • I increased the number of files with 162%
  • I reduced the average file size by 39%.

Here is how the file line count looks like:

Before: WP app source files line count

Before: WP app source files line count

After: Puzzle Frenzy source files line count

After: Puzzle Frenzy source files line count

As you can observe I still have some old large classes, but with constant refactoring I’m pretty confident that I will manage to decrease their size over time.

I’m more then excited with these changes: now the code reads better, I can understand easier what it does, and I have more confidence in it.

I strongly recommend the above-mentioned Clean Code book, it contains some priceless advice.

Happy coding!

Runtime Windows Phone App

My latest app, Runtime for WP7 is here!

RunTime is a FREE stopwatch app for Windows Phone 7.
The stopwatch continues to run in the background even if you lock the screen or leave the app.
The app allows saving laps.
The app shows both the main stopwatch timer as well as the current lap timer.

You can download the app by scanning the following QR code with Bing Vision (Press the Search button on your WP, press “Vision” then point the camera at the scree and follow the link):

Otherwise you can download it by visit the following link:

http://www.windowsphone.com/en-us/apps/e9e7b11c-242e-4d49-b4a9-c828b40f8d2d

1617e241-8731-4adc-aad0-285d534baa2c

I hope you like the app! Enjoy

Testing the Entity Framework 4.0 RIA Services Domain Service

Recently I’ve been working on refactoring and testing a Silverlight project that uses the EntityFramework.

Making all the changes of the auto-generated code in order to test it proved to be a harder task that I initially imagined.

This article summarises my findings and for getting the system ready for testing.

First of all, here is a list of links that helped me:

Testing out the Entity Framework WCF RIA Services Domain Service

WCF RIA Services Part 8 – Testing and Debugging

Testability and Entity Framework 4.0

However, none of these resources fully describe a working solution.

Here is how I finally got it working:

  • Step 1

Create an IUnitOfWork interface that will abstract the ObjectContext object used by your domain Service
Create additional operations the ObjectContext exposes as extension methods (e.g. AttachAsModified<TEntity>)

  • Step 2

Create an InMemoryUnitOfWork inheriting from IUnitOfWork (used for testing)
Create an InMemoryIObjectSet<T> inheriting from IObjectSet<T> (used for testing)

  • Step 3

Create a testing base class EFTestBaseClass for putting all the things together
Create a particular TestHelperClass for testing a particular test

There are additional important tweeks I will highlight in bold during the example.
Example:
Consider the following table in the entity container called NewTechCodeTestingEntities
An automatically generated Domain Service for manipulating it will look something like:

public class DomainService1 : LinqToEntitiesDomainService<NewTechCodeTestingEntities>
 {
 ...
 }

All the methods we are interested in testing will be hosted in this class. But instantiating it for testing will result in all operations being executed against the database. In order to avoid this situation we will have to somehow decouple this class form the EF.

(Step1)

First of we have to create the previously mentioned IUnitOfWork:

public interface IUnitOfWork
 {
 IObjectSet<Book> Books { get; }

ObjectStateManager ObjectStateManager { get; }
 int SaveChanges();
 }

This class abstracts the NewTechCodeTestingEntities.

This way we can create a special constructor for the Domain Service that we can use during testing:

public class DomainService1 : LinqToEntitiesDomainService<NewTechCodeTestingEntities>
 {
 new private readonly IUnitOfWork ObjectContext;

public DomainService1()
 {
 this.ObjectContext = base.ObjectContext;
 }

public DomainService1(IUnitOfWork unitOfWork)
 {
 this.ObjectContext = unitOfWork;
 }

...
 }

It’s important to notice how we created a new ObjectContext filed by using the new operator which either defaults to the base class ObjectContext (used for the production code when you call the parameterless contructor) or sets it to a specified one we create during testing.

An important thing to notice is the use of IObjectSet<Book> instead of ObjectSet<Book>.

The auto-generated file exposes the object in ObjectSet<T> collections.

In order to use the current approach you will have to manually change All the ObjectSet<T> declarations to IObjectSet<T> (Find and replace should do the trick in seconds)

The second thing you will have to do is make the NewTechCodeTestingEntities implement the IUnitOfWork.

The code will therefore look something like this:

public partial class NewTechCodeTestingEntities : ObjectContext, IUnitOfWork
 {
 ...
 }

Notice that these two steps (changing the collection declaration and inheriting from the IUnitOfWork) will have to be performed each time you update your EF model. I find this approach acceptable mostly because it is the only way I got the whole system to work.

Creating the extension methods are needed for keeping the auto generated code working. The only method I needed was AttachAsModified<T>:

public static class Extension
 {
 public static void AttachAsModified<TEntity&gt;(this IObjectSet<TEntity> objectSet, TEntity current, object original) where TEntity : class
 {
 throw new NotImplementedException();
 }
 }

(Step 2)

The following two classes were created for keeping the testing data:

public class InMemoryUnitOfWork : IUnitOfWork
 {
 public IObjectSet<Book> Books
 {
 get;
 set;
 }

public ObjectStateManager ObjectStateManager
 {
 get;
 set;
 }

public int SaveChanges()
 {
 throw new NotImplementedException();
 }
 }

and

public class InMemoryIObjectSet<T> : IObjectSet<T> where T : class
 {
 public InMemoryIObjectSet()
 : this(Enumerable.Empty<T>())
 {
 }

public InMemoryIObjectSet(IEnumerable<T> entities)
 {
 _set = new HashSet<T>();
 foreach (var entity in entities)
 {
 _set.Add(entity);
 }
 _queryableSet = _set.AsQueryable();
 }
 public void AddObject(T entity)
 {
 _set.Add(entity);
 }
 public void Attach(T entity)
 {
 _set.Add(entity);
 }
 public void DeleteObject(T entity)
 {
 _set.Remove(entity);
 }
 public void Detach(T entity)
 {
 _set.Remove(entity);
 }
 public Type ElementType
 {
 get { return _queryableSet.ElementType; }
 }
 public Expression Expression
 {
 get { return _queryableSet.Expression; }
 }

public IQueryProvider Provider
 {
 get { return _queryableSet.Provider; }
 }

public IEnumerator<T> GetEnumerator()
 {
 return _set.GetEnumerator();
 }

IEnumerator IEnumerable.GetEnumerator()
 {
 return GetEnumerator();
 }

readonly HashSet<T> _set;

readonly IQueryable<T> _queryableSet;
 }

If you are interested in finding more about these classes check the links at the beginning of the article.

(Step 3)

public class EFTestBaseClass
 {
 public EFTestBaseClass()
 {
 this.unitOfWork = new InMemoryUnitOfWork();
 this.controller = new DomainService1(unitOfWork);
 }

protected InMemoryUnitOfWork unitOfWork;
 protected DomainService1 controller;
 }

and

public class BooksTestHelper : EFTestBaseClass
 {
 protected IList<Book> books;

protected InMemoryIObjectSet<Book> repositoryBooks;

public BooksTestHelper()
 {
 this.PopulateCatalogueMaster();
 }

public void PopulateCatalogueMaster()
 {
 this.books = CreateCatalogueMasters().ToList();
 this.repositoryBooks = new InMemoryIObjectSet<Book&gt;(this.books);
 this.unitOfWork.Books = repositoryBooks;
 }

public static IEnumerable<Book> CreateCatalogueMasters()
 {
 yield return new Book()
 {
 Id = 1,
 Title = "Madame Bovary",
 Author = "Gustave Flauber"
 };
 yield return new Book()
 {
 Id = 2,
 Title = "The Lady of the Camellias",
 Author = "Alexandre Dumas, fils"
 };
 yield return new Book()
 {
 Id = 3,
 Title = "Notre Dame de Paris",
 Author = "Victor Hugo"
 };
 }
 }

allows us to create the following test:

 

[TestClass]
 public class BooksTest : BooksTestHelper
 {
 [TestMethod]
 public void GetBooks()
 {
 var books = controller.GetBooks();
 // insert test here
 }
 }

The tweaks that helped me get the system working were the observations highlighted in green which on top of the knowledge you get by reading the introduction articles should help you in testing your application.