
Microsoft are hosting the patterns & practices Summit Oct 12th - 16th 2009 at the Microsoft Conference Centre on Microsoft Campus in Redmond, WA.
To learn more about this event, see here: http://msdn.microsoft.com/en-us/practices/dd578307.aspx
Former Microsoft Mobility MVP 2008, 2009, 2010, 2011 now at MSFT


private TestResourceFile CreateDbFile()But even still there is a better way to solve this problem and that is to use the DeploymentItemAttribute class. It's use is simple. The following code illustrates it use:
{
dbFile = new TestResourceFile(this, "MockDatastore.sdf");
connectionString = String.Format(connectionStringPattern, dbFile.Filename);
return dbFile;
}
[TestMethod]
public void ThrowsIfNullParameterNameIsPassed()
{
using (TestResourceFile file = CreateDbFile())
{
using (Database database = new SqlDatabase(connectionString))
{
Database service = new SqlDatabase(connectionString);
ExtendedAssert.Throws(
delegate { DbParameter param = service.CreateParameter(null, "Maria Anders"); });
}
}
}
[DeploymentItem("Mobile.DataMapper.config")]
[TestClass]
public class DataContextFactoryTests
{
}The above code will copy the file "Mobile.DataMapper.config" to the test output directory. You need to ensure to set the file properties Build Action to Content and Copy to Output Directory to Copy always.<property name="datacontext" value="Mobile.DataMapper.Dialect.SqlServerCe35DataContext"/>The SqlServerCe35DataContext looks like:
public class SqlServerCe35DataContext : DataContextThe DataContext class contains the default implementation of SQL Server CE and is defined as an abstract class. It also implements the IDataContext interface which we use in our factory. This enables us to use the Plugin pattern successfully.
{
private SqlDatabase _database;
private readonly MsSqlCe35Dialect _dialect;
public SqlServerCe35DataContext()
{
_dialect = new MsSqlCe35Dialect();
}
internal override Database Database
{
get
{
if (_database == null) _database = new SqlDatabase(ConnectionString);
return _database;
}
}
internal override Dialect Dialect
{
get { return _dialect; }
}
}
public abstract class DataContext : IDataContextI've omitted many memebers as it's not important what this class does. What is important is the implementation in order to implement this pattern for devices.
{
private DbTransaction _transaction;
private string _connectionString;
public virtual void Commit()
{
if (_transaction.IsNull()) throw new InvalidOperationException("There is no transaction for this session.");
_transaction.Commit();
}
public virtual void BeginTransaction()
{
_transaction = Database.GetConnection().BeginTransaction();
}
public virtual void BeginTransaction(IsolationLevel isolationLevel)
{
_transaction = Database.GetConnection().BeginTransaction(isolationLevel);
}
internal abstract Database Database
{
get;
}
internal abstract Dialect Dialect
{
get;
}
}
public interface IDataContext : IDisposableAs I said I omitted most of the above members from the DataContext class above for clarity as I want to focus on the architecture not implementation details for this post.
{
string ConnectionString { get; set; }
//Transaction management.
void Commit();
void Rollback();
bool IsInTransaction{ get;}
void BeginTransaction();
void BeginTransaction(IsolationLevel isolationLevel);
IList<TEntity> Read<TEntity>(QueryExpressionCollection queryExpressionCollection);
IList<TEntity> Read<TEntity>(QueryExpressionCollection
queryExpressionCollection, List<Func<ObjectProperty>> columnsInScope);
IList<TEntity> FindAll<TEntity>();
TEntity Read<TEntity>(object id);
int Delete<TEntity>(TEntity entity);
TEntity Save<TEntity>(TEntity entity);
string DatabaseName { get; set; }
}
public class DataContextFactoryNotice how we have another dependency the IDataMapperConfiguration. There's no need to document this code but quite simply it's a serialized object of the XML posted earlier. We get two things from this XML file 1. The ConnectionString and 2. The concrete DataContext class that implements DataContext. Notice how we set the ConnectionString property after the type has been created. We do this because the CF only supports one Assembly.CreateInstance method that accepts the type to create.
{
private IDataContext _instance;
public DataContextFactory()
{
CreateInstance(null);
}
public DataContextFactory(IDataMapperConfiguration dataMapperConfiguration)
{
CreateInstance(dataMapperConfiguration);
}
private void CreateInstance(IDataMapperConfiguration dataMapperConfiguration)
{
if (dataMapperConfiguration == null)
dataMapperConfiguration = MapperFactory.CreateDataMapperConfiguration();
var dataContext = dataMapperConfiguration.DataContext;
var asm = Assembly.GetExecutingAssembly();
_instance = (IDataContext)asm.CreateInstance(dataContext.Value);
if (dataMapperConfiguration.HasConnectionString)
_instance.ConnectionString = dataMapperConfiguration.ConnectionString.Value;
}
public IDataContext GetDataContext
{
get
{
return _instance;
}
}
}
IDataContext context = new DataContextFactory().GetDataContext;then the consumer can work with this interface as opposed to the implementation. The consumer knows nothing about the underlying database or storage. If you changed the database from Sql CE to SQLLite for example, it is a simple case of changing the configuration file, then re-running the app.
public class CustomerRepository : Repository<Customer, int>, ICustomerRepositoryNow, there are no methods in this class but the point is to show the dependency because later, we want to use the adapter class to do some... adapting.
{
private IAdapter _adapter;
public CustomerRepository(IAdapter adapter)
{
if (adapter.IsNull()) throw new ArgumentNullException("adapter");
_adapter = adapter;
}
}
using Microsoft.Practices.Mobile.ContainerModel;
var builder = new ContainerBuilder();Then from the consumer, we can code something like the following:
builder.Register<IAdapter>(adapter => new Adapter());
builder.Register<ICustomerRepository>(repository => new CustomerRepository(Resolve<IAdapter>()));
builder.Build(container);
var customerRepository = ComponentContainer.Resolve<ICustomerRepository>();We didn't have to declare our dependency, it was injected by the framework. We just resolved the adapter when we registered the repository. Of course you need to register this dependency with the framework first. You could use the concrete type here but this means if you change implementation details, you'd have to change the implementor in more than one place.
var repository = new CustomerRepository();Where Customers is of type Collection. Well you can't out of the box as the framework doesn't provide an extension for IEnumerable foreach (which is what Collection implements).
repository.Customers.ForEach(customer => Console.WriteLine(string.Format("Customer: {0} {1}",
customer.FirstName, customer.LastName)));
Console.Read();
public class CustomerRepositoryYou can make the above call work with this simple extension for IEnumerable:
{
public CustomerRepository()
{
Customers = new Collection<Customer>()
{
new Customer()
{
FirstName = "Simon",
LastName = "Hart"
},
new Customer()
{
FirstName = "Joe",
LastName = "Bloggs"
}
};
}
public ICollection<Customer> Customers
{
get; set;
}
}
public class Customer
{
public string FirstName
{
get; set;
}
public string LastName
{
get; set;
}
}
public static class GenericIEnumerableExtensionsIt's quite simple in that it accepts one parameter, an Action delegate with one parameter - this could be extended to do whatever you want. Although the above is in line with the List.ForEach extension method.
{
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
{
action(item);
}
}
}




builderThen you can code this:
.Register<IEditCustomersView>(
c => new EditCustomersView())
.InitializedBy(
(c, v) => v.Presenter = c.Resolve<EditCustomersPresenter>());
var view = ApplicationRoot.Container.Resolve<IEditCustomersView>();This is a first cut so maybe we will see support for configuration files in the future. If I get time I'll add support for it.

Renaissance Chancery Court Hotel
252 High Holborn
London
WC1V 7EN
// Assembly System.Windows.Forms, Version 3.5.0.0
[assembly: AssemblyVersion("3.5.0.0")]
[assembly: AssemblyFlags(AssemblyNameFlags.Retargetable | AssemblyNameFlags.PublicKey)]
[assembly: SatelliteContractVersion("3.5.0.0")]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("Microsoft.WindowsCE.Forms,PublicKey=0024000004800000940000000602000000240000525341310004
000001000100bd1c7c2c1fbccfb3d24f1df7837e334e7686556e90dae8768b959497f308652686d8bebb7fc14eeb
efcfa9cffbf97d522fc678a5091cf188af5f3044b05fc3737b1c732fae4e191307da9fe29bda9c7d77e49dda0e5ed3
616b50f1e4d0a4b95fcd627157449e79cae5c5be456aa379849bd6dee7db0d5b0ff0743b0cabfa8ee7")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
Windows CE is an embedded operating system designed to run on small memory and CPU contrained devices. The OS is highly customizable. An OEM (original equipment manufacturer) can choose which bits to add and which bits to take away.
Some ISV's (independent software vendors) build their own Windows CE using a tool called Platform Builder to provision to a generic Windows CE device. Doing this allows great control over how the device will operate. This is known as Windows CE Embedded.
Pocket PC 2000 or PPC (Windows CE 3.0) was the first Pocket PC which didn't contain any GSM or radio. These are the devices you can still buy today except they are now called Windows Mobile Classic and most now are based on Windows CE 5.0. These devices were initally released with a 320x240 QVGA screen or 92DPI. So we mentioned Pocket PC is a Windows CE device.
Pocket PC/Windows Mobile devices have a different shell and a whole bunch of additional Win32 APIs and applications not seen on generic WinCE. So fundementally WinMo is a WinCE but a greatly customized version of it. The OEMs/carriers decide how the WinMo will be built, even down to what APIs are available to appliation developers and the security policy employed.
First released in 2001. The Smartphone followed the PPC that added GSM support but unlike the PPC, it didn't have a touch screen and still doesn't today. Today the Smartphone is known as the Windows Mobile Standard edition. It's worth noting that the smartphone has a much smaller screen than the Pocket PC which at the time was 176x220 QVGA - which by and large hasn't really changed much. Hi-resolution smartphone devices are rare unlike its bigger brother PPC.
First released in 2002 (based on CE 4.1) which included GSM support with 2.5G (GPRS). Eassentially this was very similar to the Pocket PC except for radio. At the time there were very few of these devices around. Today it's hard to by a regular PPC (Windows Mobile Standard) device.
Released in 2003 and based on CE 4.2. Contained many shell extensions - a whole UI overhaul and also the .NET Compact Framework v1.0 included in ROM which was a major benefit for managed developers for lots of reasons, the main one being it was able to write a managed app to load from a flash card on a cold boot (hard reset). Notice the naming change. This was when "Windows Mobile" replaced Pocket PC. But just to confuse the matter, the Smartphone was kept.
Released in 2004, but it wasn't until 2005 when Windows Mobile 5.0 devices became available from carriers and OEMs. WM 5.0 release was also when the naming changed to the following:
This was a major release for Microsoft from a platform perspective and developer story perspective. This was when Visual Studio 2005 with the .NET Compact Framework 2.0 was released which contained many many enhancements. Some of the great features from a platform perspective were an intermediate GPS driver which allowed developers to code against an API to get GPS data. Previously developers had to write very low level code to parse NMEA sentenses from a serial port (bluetooth or infrared) which was painful. In addition only one application could open the port and read data at anyone time.
Previous to WM5.0 there was no support for an embedded GPS chipset. Another cool feature was a standard Microsoft stack for communicating with the devices camera. Previously you had to code against the OEM's SDK which changed from device to device. A new flash file system was employed so files didn't exist in RAM taking up valuable memory so enabling a persistent store for all files. Some of the later devices included the .NET CF 2.0. Of course support for C# 2.0 was a massive benefit for the managed developer. The new security model was also introduced in this released - a requirement from the carriers which has caused major pain for ISV's and developers. This is not going away, sadly.
Windows Mobile 6.0 was released in 2007 and 6.1 in 2008. In fact I was in Redmond when 6.1 was released in April. Many enhancements and as more and more devices are released the uptake of VGA screens (initially supported from WM5.0) are becoming more common. Now also support for WVGA screens (640x800) is becoming popular - the new X1 from Sony and the HTC Touch Pro both support these displays. It is also worth mentioning here that WM6.1 is still based on Windows CE 5.0. It's simply shell extensions that have been added. Mainly the look and feel among other things. One thing is for sure, the performance is greatly improved over WM5.0.
See here for the Windows Mobile 5.0/6.0/6.1 SKU matrix: http://www.microsoft.com/windowsmobile/en-us/meet/version-compare.mspx
Although this post has been primarilly about Microsoft device development, in a future post I will talk about other platforms and languages/developer tools such as the iPhone, the Google Android and the Symbian OS.