Windows Azure Mobile Services is a fantastic tool and very easy to use. In this post I will show you how to use the repository pattern with the Mobile Services SDK.
If you are familiar with Entity Framework, this pattern is used in many projects and samples. You can find a definition here http://msdn.microsoft.com/en-us/library/ff649690.aspx or here http://www.codeproject.com/Articles/526874/Repositorypluspattern-2cplusdoneplusright
In this sample, we will use the portable library to share our data access layer with Windows Phone, Windows 8 and .net apps.
At the end, we will be able to inject our repository in our services / view models and to make our code testable.
At first, we will create 3 projects with the template Portable Class Library.
- MyNamespace.Models
- MyNamespace.Data
- MyNamespace.Data.MobileService
MyNamespace.Models
This project contains our data model. It’s just a simple class with describes our entities:
public class ToDoItem
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
MyNamespace.Data
This project contains the contracts (interfaces) for the repositories.
First, we will create the base interface, called IRepository. It contains all CRUD base operations.
public interface IRepository<T>
{
Task<IEnumerable<T>> GetAllAsync();
Task CreateAsync(T entity);
Task UpdateAsync(T entity);
Task RemoveAsync(T entity);
}
As explained, the repository pattern need a repository interface for each data model. Here the contract for the model ToDoItem:
public interface IToDoItemRepository : IRepository<ToDoItem>
{
}
It’s in the interface that we will add customs queries, if needed.
MyNamespace.Data.MobileService
The project contains the implementation for Mobile Services of our interfaces.
We will create a base repository with all base operations for the CRUD.
public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected IMobileServiceClient MobileServiceClient { get; set; }
protected BaseRepository(IMobileServiceClient mobileServiceClient)
{
if (mobileServiceClient == null) throw new ArgumentNullException("mobileServiceClient");
this.MobileServiceClient = mobileServiceClient;
}
protected virtual IMobileServiceTable<TEntity> GetTable()
{
return this.MobileServiceClient.GetTable<TEntity>();
}
public virtual Task<IEnumerable<TEntity>> GetAllAsync()
{
return GetTable().ToEnumerableAsync();
}
public virtual Task CreateAsync(TEntity entity)
{
return GetTable().InsertAsync(entity);
}
public virtual Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate)
{
return GetTable().Where(predicate).ToEnumerableAsync();
}
public virtual Task UpdateAsync(TEntity entity)
{
return GetTable().UpdateAsync(entity);
}
public virtual Task RemoveAsync(TEntity entity)
{
return GetTable().DeleteAsync(entity);
}
}
Now, we are ready to write the implementation of IToDoItemRepository
public class ToDoItemRepository : BaseRepository<ToDoItem>, IToDoItemRepository
{
public ToDoItemRepository(IMobileServiceClient mobileServiceClient) : base(mobileServiceClient)
{
}
}
This implementation is the base. If you have custom query, you can simply add you methods in the repository.
How to use my repository?
Our repository pattern is now implemented, we can easily use it in a Windows Phone project.
In my WP project, I really enjoy to use Caliburn.Micro and Autofac. You can add the nugget reference to Caliburn.Autofac. You can now register the repositories and the MobileServiceClient.
public class Bootstrapper : AutofacBootstrapper
{
protected override void ConfigureContainer(ContainerBuilder builder)
{
// register MobileServiceClient
builder.RegisterType<MobileServiceClient>()
.AsImplementedInterfaces()
.WithParameter("applicationUrl", "MyAppUrl")
.WithParameter("applicationKey", "MyAppKey")
.InstancePerLifetimeScope();
// register ToDoItemRepository
builder.RegisterType<ToDoItemRepository>().AsImplementedInterfaces().InstancePerLifetimeScope();
base.ConfigureContainer(builder);
}
}
Your repositories are now registered, you can call them in the viewModels.
public class MainViewModel : Screen
{
private readonly IToDoItemRepository _toDoItemRepository;
private List<ToDoItem> _toDoItems;
public MainViewModel(IToDoItemRepository toDoItemRepository)
{
_toDoItemRepository = toDoItemRepository;
}
protected override void OnActivate()
{
LoadData();
}
private async void LoadData()
{
// create an entry for the test
await _toDoItemRepository.CreateAsync(new ToDoItem {Title = "my title", Description = "my description"});
// load all data
ToDoItems = new List<ToDoItem>(await _toDoItemRepository.GetAllAsync());
}
public List<ToDoItem> ToDoItems
{
get { return _toDoItems; }
set
{
if (Equals(value, _toDoItems)) return;
_toDoItems = value;
NotifyOfPropertyChange(() => ToDoItems);
}
}
}
And voila, the repository pattern with Azure Mobile Services is now implemented. Thanks to the portable library, our data access layer is fully shareable with Win8 / .net apps.
In a next post, we will see how to create unit tests to test the view models.
Enjoy !
Source code: Mahalo.MobileServiceRepositoryPattern.7z (5,48 mb)
Quartz.NET is an open source project for job scheduling and is a port of popular open source Java job scheduling framework.
If you usually used DI in your project, you should want to used it the job. To do that with Autofac, you have to create your own factory.
At first, create the class AutofacJobFactory:
public class AutofacJobFactory : IJobFactory
{
private readonly IContainer _container;
public AutofacJobFactory(IContainer container)
{
if (container == null) throw new ArgumentNullException("container");
_container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return (IJob)_container.Resolve(bundle.JobDetail.JobType);
}
}
And now, you can configure Quartz to use AutofacJobFactory to create their jobs.
string mySchedulerCronExpression = ConfigurationManager.AppSettings["MySchedulerCronExpression"];
IContainer = container = InitializeDependencyInjectionContainer();
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = new AutofacJobFactory(container);
scheduler.Start();
IJobDetail job = JobBuilder.Create<MyJob>().WithIdentity("MyJob").Build();
ITrigger trigger =
TriggerBuilder.Create()
.WithIdentity("MyJobTrigger")
.WithCronSchedule(mySchedulerCronExpression)
.Build();
scheduler.ScheduleJob(job, trigger);
And voila :) Your job are now injected via Autofac !
I'm currently working on a new app for Windows 8: Edinburgh Airport. This app is not official and I develop it because I often need to know some stuff like the flight infos...
My app is not yet available in the store but I hope to release it very soon.
I already make some screenshot.
After a couple of month of working on my new project, I'm proud to show you the first video of MyNes, a NES emulator for Windows 8.
For all my applications, I develop specific version for many languages. Until now, I used google / bing translate. I found today a great site from Microsoft to translate specic terms from their dictionaries which are used in their products !
http://www.microsoft.com/Language/en-US/Search.aspx?sString=start+page&langID=fr-FR
Thank MS !
Caliburn.Micro for WinRT provides a full implementation of the MVVM pattern for the Windows 8 apps. The approach of a standard app is the pattern ViewFirst. This means, that you have to give the complete url of a new page to navigate.
With Caliburn.Micro you have the ViewModel first approach. With that, it's very easier to navigate from a viewModel to an other. The purpose of this post is to show you how to pass a parameter between 2 pages, so 2 viewModels.
Here a code sample :
public class ViewModel1:Screen
{
private readonly INavigationService _navigationService;
// Injection of the navigation service
public ViewModel1(INavigationService navigationService)
{
_navigationService = navigationService;
}
// Command from a button click event
public void NavigateCommand()
{
string parameter = "value";
// call NavigateToViewModel from the navigation serice
_navigationService.NavigateToViewModel<ViewModel2>(parameter);
}
}
public class ViewModel2 : Screen
{
// The property should be named Parameter
public string Parameter { get; set; }
}
Hope this helps :)
Unfortunately, XAML doesn’t provide an AppBarCommand separator control like there is in JavaScript.
To add a separator you could use a simple XAML Line element.
<Line X1="0" Y1="60" Margin="0,10,0,0" StrokeThickness="3" Stroke="White"></Line>
If your are looking HttpUtility in WinRT, you will search for a while :) All helpers to encode/decode Url / Html are now availbale int he namespace System.Net.WebUtility.
System.Net.WebUtility.HtmlDecode(string);
System.Net.WebUtility.HtmlEncode(string);
System.Net.WebUtility.UrlEncode(string);
System.Net.WebUtility.UrlDecode(string);
Hope this help !
I was searching for a global way to handle the KeyDown or KeyUp event for an entire Page in a Modern UI app.
Fortunately, I found a nice thing, it's possible to handle the KeyDown/KeyUp event for the whole page by subscribing to the events:
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
This is also very useful for my new game :)
The new cryptography API in WinRT is not very easy, specially if you know the .net API...
Here a small code to show how to use the APIs !
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
namespace SampleHashAlgorithmProvider
{
sealed partial class HashAlgProviderApp : Application
{
public HashAlgProviderApp()
{
// Initialize the application.
this.InitializeComponent();
// Hash a message.
String strAlgName = HashAlgorithmNames.Sha512;
String strMsg = "This is a message to be hashed.";
String strEncodedHash = this.SampleHashMsg(strAlgName, strMsg);
}
public String SampleHashMsg(String strAlgName, String strMsg)
{
// Convert the message string to binary data.
IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(strMsg, BinaryStringEncoding.Utf8);
// Create a HashAlgorithmProvider object.
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
// Demonstrate how to retrieve the name of the hashing algorithm.
String strAlgNameUsed = objAlgProv.AlgorithmName;
// Hash the message.
IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg);
// Verify that the hash length equals the length specified for the algorithm.
if (buffHash.Length != objAlgProv.HashLength)
{
throw new Exception("There was an error creating the hash");
}
// Convert the hash to a string (for display).
String strHashBase64 = CryptographicBuffer.EncodeToBase64String(buffHash);
// Return the encoded string
return strHashBase64;
}
}
}