Windows Support Number

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 30 August 2011

WP7Contrib: Dialling the phone number shown in a text block

Posted on 10:48 by Unknown
I wanted to be able to dial a phone number shown in a text block on a page inside an app and I knew the WP7Contrib could help. The contrib has a control called Smart Text Block, the author Mike Wolf has already written a posted about the details here. As the name suggest it has the smarts to process the text and provide an action when the highlighted text is clicked.

What I wanted to do was show how easy it is to use. There is no difficulty here at all infact, the control hides away all the complexity, like good OOD should. Also I'm no XAML Ninja like @RichGee (my coffee of choice is not a latte) so I was surprised at how little XAML I had to manipulate.

Shown below are three screenshots from the app I'm currently developing. What you can see is an embedded Bing Map (using the WP7Contrib Bing Maps Wrapper service) with a property for rent shown along with a couple of map pins for local medical facilities. When the phone number is clicked in the bottom left hand corner of the left screenshot a phone call is started.


As I said the Smart Text Block does all of this for you. All you have to do is include the required XAML and set the content for the control. I'm using the MVVM pattern to set the 'Text' property, that is it!

Shown below is the XAML required:


Shown below is the (read only) property bound to the control:

You must also remember to include the ID_CAP_PHONEDIALER in the application manifest file, more info can be found here.










Read More
Posted in WP7 WP7Contrib Phone Maps | No comments

Thursday, 25 August 2011

WP7Contrib: Criterion Factory - Location by search by latitude & longitude

Posted on 13:12 by Unknown
To kick off the series about the Criterion Factory in the Bing Maps service I thought I'd start with the easiest functionality - searching for a location using latitude & longitude.

Firstly here is the code - I have to emphasize how easy this is to use. It has taken only 5 lines of code to get the location information and the only required is a set of WP7Contrib assembly references.

private void locationByPointClick(object sender, RoutedEventArgs e)

{

var geoCoordinate = new GeoCoordinate(Convert.ToDouble(this.lat.Text), Convert.ToDouble(this.@long.Text));

 
var criterion = CriterionFactory.CreateLocationSearchForPoint(geoCoordinate);



this.bingMapsService.SearchForLocationUsingPoint(criterion)

.ObserveOnDispatcher()

.Subscribe(result =>

{

this.address.Text = result.Locations[0].Address.Locality;

this.address.Text += Environment.NewLine;

this.address.Text += result.Locations[0].Address.PostalCode;

this.address.Text += Environment.NewLine;

this.address.Text += result.Locations[0].Address.AdminDistrict;

this.address.Text += Environment.NewLine;

this.address.Text += result.Locations[0].Address.CountryRegion;

});

}

Secondly, here is a screenshot of the end-to-end example, creating the criterion and executing the SearchForLocationUsingPoint() method and showing the results on the emulator, you can also see the logging in the visual studio output window.


I've highlight the line we are interested, the creation of the criterion for use with the service. As I said this was probably the easiest one to document, there is only one overload for this method, shown below. The 'includeEntities' parameter allows you to define what information will be returned for the query, as the documentation says this is optional, hence the overloaded method. More info about the types supported can be found on MSDN.

As you can see we do some primitive validation of the parameters used to create the criterion - we never to do much more than check for nulls if the parameter is required or an explicit optional parameter. These simple rules have been extracted from the MSDN documentation. Later in this series we will see validation rules for more complicated parameters.

#region LocationSearchForPoint



public static ILocationSearchPointCriterion CreateLocationSearchForPoint(GeoCoordinate point)

{

return CreateLocationSearchForPoint(point, new List<LocationEntity>());

}



public static ILocationSearchPointCriterion CreateLocationSearchForPoint(GeoCoordinate point, IList<LocationEntity> includeEntities)

{

if (point == null)

throw new ArgumentNullException("point", "Point is null.");



if (point == GeoCoordinate.Unknown)

throw new ArgumentException("Point is unknown.", "point");



if (includeEntities == null)

throw new ArgumentNullException("includeEntities", "Include Entities can not be null.");



var criterion = new LocationSearchCriterion { Point = point };

criterion.IncludedEntities.AddRange(includeEntities);



return criterion;

}



#endregion


You'll also notice from the above code snippet the return value for the overloaded methods - ILocationSearchPointCriterion. The Bing Maps service only accepts a criterion interface as a parameter, thes reason for this is to reduced the number of parameters. The Bing Maps service interface for searching for locations is shown below:

/// <summary>

/// Defines the interface for searching for location information using the Bing Maps API.

/// </summary>

public interface IBingLocationService

{

IObservable<LocationSearchResult> SearchForLocationUsingAddress(ILocationSearchAddressCriterion criterion);

IObservable<LocationSearchResult> SearchForLocationUsingPoint(ILocationSearchPointCriterion criterion);

IObservable<LocationSearchResult> FindLocationUsingQuery(ILocationSearchQueryCriterion criterion);

}


The ILocationSearchPointCriterion is a simple read-only interface preventing changing of a criterion once created (if you only have a reference to the interface), see below. This was explicitly done because the criterion has to be immutable because it is used as part of the internal caching key inside the Bing Maps service. Similarly we want to be able to clone the criterion hence the implementation of the WP7Contrib interface ICloneable.

public interface ILocationSearchPointCriterion : ICloneable<ILocationSearchPointCriterion>

{

GeoCoordinate Point { get; }

ObservableCollection<LocationEntity> IncludedEntities { get; }



bool HasPoint { get; }

bool HasIncludedEntities { get; }

}


This interface is implemented by the LocationSearchCriterion class, this is a bindable model class that implements public getters & setters for the Point & IncludedEntities parameters. In theory you could bind these properties directly to the UI and then pass the class to the service without needing an intermediate View Model variables\properties. This class also implements the equality operators and IEquatable interface, this is required again for the internal caching in the Bing Maps service.

I've shown the LocationSearchCriterion class below, in future posts I'm nothing to show criterion class unless there is a special case as they are rather long in length.

public class LocationSearchCriterion : BaseModel, ICriterion<LocationSearchCriterion>,

IEquatable<LocationSearchCriterion>,

ICloneable<LocationSearchCriterion>,

ILocationSearchQueryCriterion,

ILocationSearchAddressCriterion,

ILocationSearchPointCriterion

{

private Address address;

private GeoCoordinate point;

private string query;

private ObservableCollection<LocationEntity> includeEntities;



public LocationSearchCriterion()

{

this.Reset();

}



public Address Address

{

get

{

return address;

}

set

{

this.SetPropertyAndNotify(ref this.address, value, () => this.Address);

}

}



public bool HasAddress

{

get { return this.address != null && this.address != Address.Empty; }

}



public GeoCoordinate Point

{

get

{

return this.point;

}

set

{

this.SetPropertyAndNotify(ref this.point, value, () => this.Point);

}

}



public bool HasPoint

{

get { return this.point != null && this.point != GeoCoordinate.Unknown; }

}



public string Query

{

get

{

return this.query;

}

set

{

this.SetPropertyAndNotify(ref this.query, value, () => this.Query);

}

}



public bool HasQuery

{

get { return string.IsNullOrEmpty(this.query); }

}



public ObservableCollection<LocationEntity> IncludedEntities

{

get

{

return this.includeEntities;

}

set

{

this.SetPropertyAndNotify(ref this.includeEntities, value, () => this.IncludedEntities);

}

}



public bool HasIncludedEntities

{

get { return this.includeEntities != null && this.includeEntities.Count != 0; }

}



public LocationSearchCriterion Reset()

{

this.address = new Address();

this.point = new GeoCoordinate();

this.query = null;



this.includeEntities = new ObservableCollection<LocationEntity>();



return this;

}



public static bool operator ==(LocationSearchCriterion lsc1, LocationSearchCriterion lsc2)

{

return Equals(lsc1, lsc2);

}



public static bool operator !=(LocationSearchCriterion lsc1, LocationSearchCriterion lsc2)

{

return !Equals(lsc1, lsc2);

}



public override bool Equals(object obj)

{

if (ReferenceEquals(null, obj))

{

return false;

}



return obj is LocationSearchCriterion && this.Equals((LocationSearchCriterion)obj);

}



public override int GetHashCode()

{

return this.CombineHashCodes(this.Address, this.Point);

}



public bool Equals(LocationSearchCriterion criterion)

{

if (ReferenceEquals(null, criterion))

{

return false;

}



if (this.Address != criterion.Address)

{

return false;

}



if (this.Point != criterion.Point)

{

return false;

}



if (this.Query != criterion.Query)

{

return false;

}



return true;

}



ILocationSearchAddressCriterion ICloneable<ILocationSearchAddressCriterion>.ShallowClone()

{

return this.ShallowClone();

}



ILocationSearchPointCriterion ICloneable<ILocationSearchPointCriterion>.ShallowClone()

{

return this.ShallowClone();

}



ILocationSearchQueryCriterion ICloneable<ILocationSearchQueryCriterion>.ShallowClone()

{

return this.ShallowClone();

}



public LocationSearchCriterion ShallowClone()

{

var criterion = new LocationSearchCriterion

{

Address = this.Address,

Point = this.Point,

Query = this.Query

};

return criterion;

}



ILocationSearchAddressCriterion ICloneable<ILocationSearchAddressCriterion>.DeepClone()

{

return this.DeepClone();

}



ILocationSearchPointCriterion ICloneable<ILocationSearchPointCriterion>.DeepClone()

{

return this.DeepClone();

}



ILocationSearchQueryCriterion ICloneable<ILocationSearchQueryCriterion>.DeepClone()

{

return this.DeepClone();

}



public LocationSearchCriterion DeepClone()

{

var criterion = new LocationSearchCriterion

{

Query = this.Query

};



if (this.HasAddress)

criterion.Address = this.Address.DeepClone();



if (this.HasPoint)

criterion.Point = new GeoCoordinate(this.Point.Latitude, this.Point.Longitude);



return criterion;

}

}


That pretty covers it!

If you want to use the demo you can, it can found in the WP7Contrib Spikes in the 'BingMaps_CriterionFactory' directory. You'll have to have a Bing AppID to use the service & demo, you can register here.




Read More
Posted in WP7Contrib Bing Maps WP7 | No comments

WP7Contrib: Bing Maps REST Services Wrapper - Criterion Factory

Posted on 10:23 by Unknown
Today I'm starting a series of post about Criterion Factory in the Bing Maps service in the WP7Contrib. I'm not sure how many posts there will be but I expect there to be a few, every time I add one I'll update the list below.

Rich & I have written several posts already about using the Bing Maps service, these have focused around the  Location, Routes & Search functionality provided by the Bing Maps REST API and how easily you can get data back without having to deal with a single HttpWebRequest!. If you've read any of these posts you'll have notice the use of the Criterion Factory to construct the query passed to the service methods.

Put simply the Criterion Factory is there to help construct queries because the number of parameters can be confusing and you won't always need to specify every parameter for a particular use case.

A quick refresh, shown below is a prime example of how to use the Bing Maps Wrapper service, it's returning the current location for a post code (zip code):

public partial class MainPage : PhoneApplicationPage
{
private readonly IBingMapsService bingMapsService = null;

// Constructor
public MainPage()
{
InitializeComponent();

this.bingMapsService = new BingMapsService("Your credentials id", "Your app id");
}

private void getAddress_Click(object sender, RoutedEventArgs e)
{
var criterion = CriterionFactory.CreateLocationSearchForAddress(this.postCode.Text);

this.bingMapsService.SearchForLocationUsingAddress(criterion)
.ObserveOnDispatcher()
.Subscribe(result =>
{
this.address.Text = result.Locations[0].Address.Locality;
this.address.Text += Environment.NewLine;
this.address.Text += result.Locations[0].Address.PostalCode;
this.address.Text += Environment.NewLine;
this.address.Text += result.Locations[0].Address.AdminDistrict;
this.address.Text += Environment.NewLine;
this.address.Text += result.Locations[0].Address.CountryRegion;
});
}
}

As I said I'll update the list below with every post about the Criterion Factory:

1. Location search by Latitude & Longitude
2 .Location search by Address
3. Calculating a Route


Read More
Posted in Bing Maps, WP7 WP7Contrib CodePlex | No comments

Tuesday, 23 August 2011

Using Bouncy Castle on Windows Phone 7

Posted on 10:37 by Unknown
I'm currently working on a port of an application from iPhone onto WP7 and the local content has to be decrypted on the device. The content was original encrypted for a different platform and the cipher & padding used are not supported in the Silverlight version for WP7. The content was encrypted using the AES symmetric algorithm with an ECB cipher and PCKS5 padding. As stated this combination is not supported by the AESManaged  class available in the System.Security.Cryptography namespace. The documentation states only the following is supported:

'The cipher mode is always CBC, and the padding mode is always PKCS7'

I'm not sure why this is, but I'm aware that ECB is no longer viewed a secure cipher - the choice to use this was out of our hands. The next stage was to find OSS library for WP7. After several recommendations we decided to use Bouncy Castle. BC (Bouncy Castle) is a well established cryptography library from the Java world with a port to C#. The don't offer a WP7 specific build so I decided to re-compile for WP7 & WP7.1 - both of these are available for download at the bottom of the post. I used the 1.7 source code with IDEA support, available here.

The only issue to arise was during testing the compiled assembly, the Enum class inside BC didn't like some of the reflection code, specifically throwing exception when attempting to get value from an instance of the FieldInfo class, see below:



 I had to add the following conditional compile statements to get the enum parsing to work as expected. After that everything was groovy:


I probably could have refactored the method completely but I didn't, I'm not overly familiar with the code base. This means if you download and use the binaries below you might well find other issues with the BC code base running on WP7. Make sure you write enough tests to cover all your edge cases!

Shown below is the code I used to decrypt the test data. The BC specific code is highlighted in bold, as you can see setting up the AES cipher is easy and the whole process of decrypting data is handled in 5 lines of code. The 'false' parameter passed to the Init() method defines the cipher as a decrypting cipher, using 'true' would mean it would encrypt.

private void button1_Click(object sender, RoutedEventArgs e)

{

// Get the encrypted data from the WP7 installation directory

var stream = Application.GetResourceStream(new Uri("test.data", UriKind.Relative)).Stream;

var encryptedData = new byte[stream.Length];

stream.Read(encryptedData, 0, encryptedData.Length);



// encryption key...

var key = Encoding.UTF8.GetBytes("12345678qwertyui");



// AES algorthim with ECB cipher & PKCS5 padding...

var cipher = CipherUtilities.GetCipher("AES/ECB/PKCS5Padding");



// Initialise the cipher...

cipher.Init(false, new KeyParameter(key));



// Decrypt the data and write the 'final' byte stream...

var bytes = cipher.ProcessBytes(encryptedData);

var final = cipher.DoFinal();



// Write the decrypt bytes & final to memory...

var decryptedStream = new MemoryStream(bytes.Length);

decryptedStream.Write(bytes, 0, bytes.Length);

decryptedStream.Write(final, 0, final.Length);

decryptedStream.Flush();



var decryptedData = new byte[decryptedStream.Length];

decryptedStream.Read(decryptedData, 0, (int)decryptedStream.Length);



// Convert the decrypted data to a string value...

var result = Encoding.UTF8.GetString(decryptedData, 0, decryptedData.Length);

Debug.WriteLine(result);

}


That pretty much covers where I got to when using Bouncy Castle, I hope this helps someone in the future.







Read More
Posted in WP7 cryptography bouncy castle | No comments

Sunday, 21 August 2011

SharpSerializer for Windows Phone 7

Posted on 08:24 by Unknown
There's a new binary serializer available for WP7 - SharpSerializer. It 's OSS and is currently hosted on CodePlex. Available via NuGet as well.

I received an anonymous comment the other day on a blog post about serialisation performance on WP7. So I thought I would re-run the test app and see how it compared, the original post can be found here. My first attempt failed because the NuGet packages were invalid, so after the author had corrected this I decided to run the test again. This time though I got the latest code and explicitly compiled this as  a WP7 class library.

So I ran the same test, binary serialize a collection containing 1000 items and display the performance results to the output window in visual studio:


The results don't lie, sharpSerializer is good, but SilverlightSerializer still has it for me.

Good to see some competition in this space I'll be keeping an eye on this project.





Read More
Posted in WP7 Serialisation | No comments

Be careful of the culture when using Bing Maps REST API

Posted on 06:28 by Unknown
When developing the Bing Maps Wrapper service for the WP7Contrib we weren't aware of the importance of the instance of the CultureInfo class used to format the geo-coordinate data when building the URL parameters.

This was for the simple reason, being based in the UK we were relying on the default culture, which happens to be 'en-US'  and this culture formats decimal numbers in the required format for calls to the Bing Maps REST API. The documentation on MSDN does state this, but does not make it very clear.

Show below is the formatting for a couple of different cultures, what you'll see is the formatting for the Lat & Long for the Netherlands & Russian cultures is different to the rest. They both use commas as the decimal point.


When the Lat & Long are used to format the URL parameter they need to be in InvariantCulture so that your URL looks like the following:


If I force the Bing Maps Service to use the Netherlands culture with the code shown below (taken from inside the service class):


Then I get the following output in visual studio; What's interesting is the Bing Maps server doesn't return an error code (it still returns a status code of 200) even though the location data is formatted incorrectly. This is why I have added the boolean checks 'HasSucceeded' & 'HasLocations' to the result class.


So now when formatting floating point numbers for use with the Bings Maps API we use the following style inside the Bing Maps Wrapper service:

Thanks to Derek Lakin for pointing this one out, you can see multi-culture Bing Maps REST API requests being used in his WP7 app 'Car Finder'.








Read More
Posted in CodePlex, CultureInfo, WP7, WP7Contrib | No comments

Friday, 19 August 2011

WP7Contrib: Getting debug information from the NuGet packages

Posted on 07:09 by Unknown
When using the WP7Contrib packages from nuget.org you will be using the release build versions of the assemblies. Unfortunately what you won't get is the debug information generated by the services and other classes in the contrib. What is detailed below is steps you can use to get this debug information when using the packages.

I am aware NuGet now supports the publication of PDBs & symbols to symbolsource.org (more info can be found here). We haven't yet got round to factoring this into our publication process. When I say process, I mean when I use NuGet Package Explorer to do the publish to NuGet. I'm not sure the explorer currently supports this feature (hopefully I'm wrong). When this is done you'll be able to step through the contrib code base.

We also provide another way to get debug information at runtime via the ILog interface. The caching, communications & services namespaces make use of this interface. Like all dependencies in the contrib it can be injected in via the class constructor - all these classes provide overload constructors for this.

So the interface looks like this:

public interface ILog

{

ILog Write(string message);



ILog Write(string message, params object[] args);



ILog Write(string message, Exception exception);



ILog WriteDiagnostics();

}


Before I show how I implement a local version of this to help debug an application, lets see how an example application using the Bing Maps Wrapper service (out of the box) doesn't produce any logging information.

So the following code makes a call out to Bings Maps API to get the location information for a post code (zip code). As you can see from the highlighted box the only output is the write line from the Rx subscriber when the result is returned.



Now this is great when the code has executed the 'happy path', but what happens if something goes wrong because of bad input data or there is a bug in the contrib? You're not going to see anything helpful coming out of the contrib apart from maybe a formatted exception.

This is where the ILog interface comes into play, if you have an implementation that uses the Debug.WriteLine() method you can quickly see what is going on under the covers.

Shown below is a class I drop into any solution using the NuGet versions of the contrib, you can get a copy here  (DebugLog.cs):

public sealed class DebugLog : ILog

{

private const string DateFormat = "dd-MM-yyyy HH:mm:ss.fff";



public ILog Write(string message)

{

Debug.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString(DateFormat), message));



return this;

}



public ILog Write(string message, params object[] args)

{

var messageWithParameters = string.Format(message, args);

Debug.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString(DateFormat), messageWithParameters));



return this;

}



public ILog Write(string message, Exception exception)

{

var date = DateTime.Now.ToString(DateFormat);



Debug.WriteLine(string.Format("{0} - {1}", date, message));

Debug.WriteLine((string.Format("{0} - Exception '{1}'", date, exception)));



return this;

}



public ILog WriteDiagnostics()

{

return this;

}

}


You then have to wire this into the contrib classes that accept an instance of the ILog interface. Shown below is the re-worked example from above.


As you can see you get a lot of information in real-time about what's going on inside the contrib. In this case you can see the call out to the URL endpoint, the response headers returned, the deserialization time for the returned data and finally the result being added to the In Memory Cache Provider.

I hope this helps someone trying to use the contrib :).

Also, we don't currently use any AOP tools to weave in debug\trace information but this might well be added in the future, and we are going to improve our constructors for classes - to make these easier to use for people not working with DI frameworks.








Read More
Posted in Debugging, WP7 WP7Contrib CodePlex | No comments

Wednesday, 17 August 2011

Manipulating web browser scroll position on Windows Phone 7

Posted on 05:30 by Unknown
Manipulating the browser control position on WP7 is relatively straight forward, all you need to is a couple of calls out to javascript using the InvokeScript method on the browser control. In fact this is the same pattern provided in the desktop version of WPF & Silverlight.

The only requirement is the ability to include a couple of javascript functions in a web page. Now this is only possible if you either have control over the remote content or you're using local content on the device. Recently I've been working on a phone app that uses local content. This content is designed for a particular profession who need to access to detailed and intricate data in a fast and easy manner. Each page conforms to a standard model with a simple breadcrumb style at the top to help with navigation and very detail data with embedded links. When  a page is bookmarked or the back button is used to navigate the app we are need to get the scroll positions.

So shown below is a simple test app for manipulating the scroll position, as you can see it has a set of buttons for  changing the scroll positions programmatically, so when I start the app and get the vertical & horizontal scroll positions they return '0' as expected. After zooming in and moving around the page and then getting the positions again you can see they have changed. Similarly if I enter a position and click a 'Set' button you would observe the browser scroll position changing:



So the C# code to call out to javascript is very simple and as I said before this is exactly same code I would use for WPF or desktop Silverlight application:

private void setVScrollClick(object sender, RoutedEventArgs e)
{
try
{
this.webBrowser.InvokeScript("setVerticalScrollPosition", this.vScrollPos.Text);
}
catch (Exception exn)
{
}
}

private void getVScrollClick(object sender, RoutedEventArgs e)
{
try
{
object pos = this.webBrowser.InvokeScript("getVerticalScrollPosition");
this.vScrollPos.Text = pos.ToString();
}
catch(Exception exn)
{
}
}

private void getHScrollClick(object sender, RoutedEventArgs e)
{
try
{
object pos = this.webBrowser.InvokeScript("getHorizontalScrollPosition");
this.hScrollPos.Text = pos.ToString();
}
catch (Exception exn)
{
}
}

private void setHScrollClick(object sender, RoutedEventArgs e)
{
try
{
this.webBrowser.InvokeScript("setHorizontalScrollPosition", this.hScrollPos.Text);
}
catch (Exception exn)
{
}
}

And finally the javascript, as I said you'll need some ability to get these functions included in the page directly or into a javascript file. We had the ability when the local content was installed on the device to inject these functions into the javascript  file:

function getVerticalScrollPosition() {
return document.body.scrollTop.toString();
}
function setVerticalScrollPosition(position) {
document.body.scrollTop = position;
}
function getHorizontalScrollPosition() {
return document.body.scrollLeft.toString();
}
function setHorizontalScrollPosition(position) {
document.body.scrollLeft = position;
}

There is one small but important fact to remember when calling out to javascript from managed code is any value returned from javascript has to be a string value. This means if the 'getVerticalScrollPosition' method above returned a number value it would not be marshalled to managed code.

The application I used for this post can be found here.






Read More
Posted in WP7 Javascript web browser | No comments

Monday, 15 August 2011

Manually build WP7 solution with MSBuild on win64

Posted on 16:11 by Unknown
When manually building a WP7 solution file on a win64 machine make sure you use the correct version of msbuild.exe - if you don't you'll get the loads of 'failed to load assembly' messages.

The message that gives it away is 'Could not load file or assembly PresentationCore':

C:\Program Files (x86)\MSBuild\Microsoft\Silverlight for Phone\v4.0\Microsoft.Silverlight.Common.targets(188,9): error MSB4018: S
ystem.IO.FileLoadException: Could not load file or assembly 'PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=3
1bf3856ad364e35' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047
)\r [C:\Work\Temp\PhoneApp2\PhoneApp2\PhoneApp2.csproj]


So get it to build you have to use the msbuild.exe from the standard .net directory - C:\Windows\Microsoft.NET\Framework\v4.0.30319.

So the following will fail:


And the following will succeed:


Read More
Posted in WP7 MSBuild | No comments

WP7Contrib: 'IsCachable' is here to help!

Posted on 15:03 by Unknown

We've added the method 'IsCachable()' to the ICacheProvider to help diagnose and test suitability of entities for caching.

It can be used in a live application but we expect it to be more likely used during testing. We don't see any problems with exposing this method on the interface as it has no side affects for the entity being tested or for the cache provider being evaluated against. Any exceptions which occur whilst calling this method are caught and not exposed.

The complete signature for the method is shown below:

bool IsCacheable<T>(T value, ref IEnumerable<Type> failingTypes) where T : class;


The suitability for caching will be returned as the boolean result and any failing types are returned via the ref parameter 'faillingTypes'. Obviously the internal implementation is dependent on the cache provider being used. The method will always return true for the In Memory & Null Cache Providers because neither of these implementations have to manipulate the data being stored in the cache provider.

The implementation was initially created for was the Isolated Storage Cache Provider. This uses the SilverlightSerializer internally and historically this gave rather confusing exception messages, but since Mike has released v2 these have greatly improved (see my previous post). We still went ahead with adding this functionality to aid testing and we completed it before Mike released the new version :)

Basically the implementation re-curses the object graph extracting the object properties which are reference types and  marked for serialisation (i.e. they don't have the 'DoNotSerialize' attribute). Common types which are known to be serializable are ignored - string, List string[], List, double[]... We also ignore duplicate types as well, so if an object graph has a circular reference or a descendant entity contains a type for checking as an ancestor it will be ignored because the ancestor will have already added this to the list of types to be checked.

So lets see how this works with a simple succeeding unit test:

[TestMethod]

public void ShouldBeAbleToCacheComplexModel()

{

// Given we have an isolated storage cache provider...

var cacheProvider = new IsolatedStorageCacheProvider("IsolatedStorageCacheProviderTests", Enumerable.Empty<Assembly>());



// Given we have a model we want to check for cacheability...

var model = new SuccessfulComplexModel

{

FirstName = "ollie",

LastName = "riches",

Location = new GeoCoordinate(51.554111, -0.072784)

};

model.Area = new LocationRect(model.Location, 10, 10);

model.Stuff.Add("Stuff1");

model.Stuff.Add("Stuff2");

model.Stuff.Add("Stuff3");



// When we test for cacheability...

IEnumerable<Type> failingTypes = null;

var cacheable = cacheProvider.IsCacheable(model, ref failingTypes);



//Then we expect it to be cacheable...

Assert.IsTrue(cacheable);

Assert.IsFalse(failingTypes.Any());

}


The type being checked here is a relatively simple complex type! See the class diagram below, it contains 2 String properties, 2 generic collections as well as a GeoCoordinate & LocationRect property.

When we run the tests in debug when get the following returned in the output window in visual studio. The highlighted area shows the types that have been checked for compatibility with the SilverlightSerializer and since the <ROOT> type (SuccessfulComplexModel) is serializable we skip over the rest of the types because they are all descendants of the <ROOT>.
.


A failing test produces the following output in visual studio, what you can see is two MissingMethodException messages being generated. These are coming from SilverlightSerializer, the actual (exception) message is not being displayed here but it will have detailed information about the failing type (since v2 of SilverlightSerializer).

What you can see below the exception messages is the types we've attempted to serialize and you can see the <ROOT> failed to serialize as well as the descendant property 'Url' - in fact the <ROOT> failed to serialize because of the failing descendant and this is why we recurse down the object graph looking for the all types which will fail to be serialized.


That pretty much covers it, hope this helps anyone using the Isolated Cache Provider and writing tests for entities you wish to cache.






Read More
Posted in WP7 WP7Contrib SilverlightSerializer C# | No comments
Newer Posts Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • Unit testing Rx methods Timeout & Retry with moq
    Earlier this week I was trying to unit test an asynchronous service (Foo) which used another asynchronous service (Bar) internally and ran i...
  • Understanding RefCount in Reactive Extensions
    A couple of weeks ago  @LordHanson  & I ran into an issue converting a stateless async service exposed as an Rx cold observable to a  co...
  • StructureMap: ILifecycle
    The other day I wanted to control the scope of a service inside a web based app with semantics which didn't fit either 'HttpContextS...
  • MVVM anti-pattern: Injecting the IoC container into a View Model
    This is another anti-pattern I've seen a lot recently, the dynamic use of the IoC container inside a view model to resolve child view mo...
  • How many pins can Bing Maps handle in a WP7 app - part 1
    part2 -  http://awkwardcoder.blogspot.com/2011/10/how-many-pins-can-bing-maps-handle-in.html part3 -  http://awkwardcoder.blogspot.com/2011/...
  • Bad developers love 'The Daily WTF'
    When 'The Daily WTF' started up back in 2003/2004 it was a great laugh looking at shocking code other developers wrote, but after a ...
  • Using CompositeDisposable in base classes
    To help make an object eligible for collection by the GC (garbage collector) one would implement the IDisposable interface. Executing the di...
  • Implementing a busy indicator using a visual overlay in MVVM
    This is a technique we use at work to lock the UI whilst some long running process is happening - preventing the user clicking on stuff whil...
  • Daily Dilbert Service - the most important service I've ever written...
    NuGet package available here ... First off a big shout to  @hamish  &  @leeoades  on this one - I'm just blogging about it. At work ...
  • Comparing performance of .Net 4.5 to .Net 4.0 for WPF
    Currently I'm working on a .Net 4.0 WPF app and we've had some discussion about moving to .Net 4.5, we don't get to make the dec...

Categories

  • .Net
  • .Net 4.5
  • Abstractions
  • Advertising
  • Agile
  • Agile Courage
  • AOP
  • Async
  • automated testing
  • Azure
  • Azure IIS RESTful development
  • BDD
  • Bing Maps
  • Bounded Context
  • C#
  • C# 5.0
  • Caching
  • Chocolatey
  • CLoud
  • CodePlex
  • Coding
  • Coding Building CI Testing
  • Coding C#
  • coding C# IoC StructureMap
  • Coding Functional-Programming
  • Coding REST Knowledge
  • Coding Services
  • Coding TDD Refactoring Agile
  • Command
  • continuous testing
  • coupling
  • CultureInfo
  • DAL
  • databases
  • DDD
  • DDD Coaching
  • DDD Domain Events Auditing nHibernate
  • DDD Entities Value Objects
  • Debugging
  • Design Patterns
  • Design Patterns Databases Auditing
  • Developement
  • Development
  • Development Coding
  • Development Process
  • Development unit testing
  • Development VS 2011
  • Diagnostics
  • Disposable
  • Exceptions
  • FINDaPAD
  • FindaPad Property Rental Windows Phone 7 Mobile Devices
  • Fun Coding Duct-Tape
  • Hotfixes
  • integration testing
  • IoC
  • jasmine
  • javascript
  • Jobs Development
  • LINQ
  • marketplace
  • Mobile Devices
  • Mocking
  • MSDN Coding
  • MSpec
  • Multilingual
  • MVC
  • MVVM
  • nCrunch
  • nHbiernate Repository Pattern Criteria
  • nHibernate Auditing Design Fluent
  • nHibnerate Entities Events Listeners
  • node.js
  • nodes.js
  • Nokia
  • NoSQL RavenDB Azure Development
  • Observations
  • OO
  • ORM
  • Performance
  • Portable Class Library
  • Portable Library
  • PostSharp
  • Process
  • Rants
  • RavenDB IIS 7.5 Development
  • Reactive
  • Reactive Extension
  • Reactive Extensions
  • ReadOnlyCollections
  • Resharper
  • REST Distributed-Systems
  • REST HTTP
  • rest web
  • RESTful
  • Rx
  • Serialization
  • Silverlight
  • Silverlight Installation
  • Task
  • TDD
  • TDD IoC DI
  • TDD Mocking
  • TDD Team Observation
  • Telerik
  • testing
  • threading
  • TPL
  • UI
  • Undo-Redo
  • unit testing
  • ViewModels
  • VS 2012
  • wcf
  • web api
  • Web Services
  • web services mobile devices data
  • WebAPI
  • Windows
  • Windows 8
  • windows phone
  • Windows Phone 7
  • WP7
  • WP7 Bing Maps Development Network HTTP
  • WP7 Bing Maps Development UK Crime
  • WP7 Bing Maps Development UK Crime Clustering
  • WP7 Bing Maps Development UK Polygons Clustering Performance
  • WP7 cryptography bouncy castle
  • WP7 Cultures C#
  • WP7 feedback development app store
  • WP7 Javascript web browser
  • WP7 MSBuild
  • WP7 ORM Databases performance
  • WP7 Serialisation
  • WP7 SilverlightSerializer C#
  • WP7 sqlite performance development
  • WP7 WP7Contrib Bing Maps Development
  • WP7 WP7Contrib Bing Maps Polygon Development
  • WP7 WP7Contrib CodePlex
  • WP7 WP7Contrib CodePlex Bing Maps Development
  • WP7 WP7Contrib CodePlex ObservableCollection
  • WP7 WP7Contrib ILMerge .Net
  • WP7 WP7Contrib Phone Maps
  • WP7 WP7Contrib SilverlightSerializer C#
  • WP7Contrib
  • WP7Contrib Bing Maps WP7
  • WP7Contrib WP7 Geo-Location development C#
  • WP7Contrib WP7 HTTP Compression
  • WP7Contrib WP7 Url Development Rx
  • WP7Dev
  • WPF
  • WPF Cultures
  • WuApi
  • XAML

Blog Archive

  • ►  2013 (16)
    • ►  November (5)
    • ►  September (3)
    • ►  August (1)
    • ►  July (1)
    • ►  June (3)
    • ►  May (2)
    • ►  January (1)
  • ►  2012 (44)
    • ►  November (2)
    • ►  October (8)
    • ►  September (5)
    • ►  August (2)
    • ►  July (4)
    • ►  June (3)
    • ►  May (1)
    • ►  April (2)
    • ►  March (13)
    • ►  February (4)
  • ▼  2011 (52)
    • ►  December (3)
    • ►  November (5)
    • ►  October (7)
    • ►  September (7)
    • ▼  August (11)
      • WP7Contrib: Dialling the phone number shown in a t...
      • WP7Contrib: Criterion Factory - Location by search...
      • WP7Contrib: Bing Maps REST Services Wrapper - Crit...
      • Using Bouncy Castle on Windows Phone 7
      • SharpSerializer for Windows Phone 7
      • Be careful of the culture when using Bing Maps RES...
      • WP7Contrib: Getting debug information from the NuG...
      • Manipulating web browser scroll position on Window...
      • Manually build WP7 solution with MSBuild on win64
      • WP7Contrib: 'IsCachable' is here to help!
      • WP7Contrib: Updated version of SilverlightSerializer
    • ►  July (4)
    • ►  May (2)
    • ►  April (1)
    • ►  March (5)
    • ►  February (3)
    • ►  January (4)
  • ►  2010 (1)
    • ►  August (1)
  • ►  2009 (32)
    • ►  December (3)
    • ►  November (7)
    • ►  October (6)
    • ►  September (11)
    • ►  April (1)
    • ►  March (4)
Powered by Blogger.

About Me

Unknown
View my complete profile