I've always enjoyed working with the Caliburn framework for WPF and Silverlight, having the view and view model wired with so many conventions makes creating a rich view model really easy. So one of the first things I did after getting a hold of the Windows Phone 7 CTP was to try and get Caliburn working.
On a side note Rob Eisenberg has released Caliburn Micro which is a slimmed down version of Caliburn that also targets WP7. It's a great little library but has some problems in the WP7 version due to the incomplete binding infrastructure in WP7 (lack of binding on anything not subclassing FrameworkElement), this makes Action Parameters impossible. The original Caliburn doesn't have this problem due to a more complicated code base.
Getting Caliburn 1.1 to compile for WP7 wasn't too difficult, some features like DefaultWindowManager were dropped and since we don't have support for System.Reflection.Emit then some of the code in DelegateFactory didn't work. In the end I replaced with some anonymous methods using simple reflection. Not as elegant and probably not as performant.
As a bonus I've included the Ninject library and Caliburn Ninject adapter.
So how do get this whole thing going? First we have to look at some of the ways the Windows Phone 7 framework expects things to work and how it impacts Caliburn. These also affect Caliburn Micro as well.
The major one is that WP7 expects the RootVisual to be a PhoneApplicationFrame, this provides a lot of the navigation support as well as Orientations. You can circumvent this but from comments from Microsoft you'll be fighting the framework the entire way (for example WP7 will close an application that hasn't navigated within the first ten seconds). If you end up supporting the navigation metaphor essentially you're now using a "view first" approach rather than the default Caliburn approach of "view model first".
publicpartialclassShellView
{
privatereadonlyIServiceLocator serviceLocator;
privatereadonlyIBinder binder;
public ShellView(IServiceLocator serviceLocator, IBinder binder)
var viewModelTypeName = viewType.FullName.Replace("View", "ViewModel");
var viewModelType =Type.GetType(viewModelTypeName);
return serviceLocator.GetInstance(viewModelType);
}
}
Unlike Silverlight 4 we can't alter the content loader in PhoneApplicationFrame, so for navigation we'll need to handle when the frame changes it's current page and wire in a view model at this state. We can do this via a "view model locator" in the same faction as the default "view locator", but for the moment we'll manually wire the view and the view model. Caliburn Micro has slightly better support for the "view first" approach and I'll tackle that next. Below is a link containing the assemblies and a sample project.
Most of the time I do any database interaction I follow a "Unit of Work" pattern. This allows good control over when work is submitted to the database, in terms of the Entity Framework, the Unit of Work controls the lifetime of the ObjectContext.
The implementation is pretty simple, we have a UnitOfWork static class that provides easy access to the current UOW as well as starting and disposing. We then have our IUnitOfWork which is where the work of accessing repositories and submitting changes to the database will be done. We then implement that with EntityUnitOfWork.
I like to follow the approach of "Unit of Work per Request" for web applications and usually handle this with an IHttpModule that manages it for me. However for MVC I wanted to try something different. One of the reasons I didn't like Module approach for MVC was that the UnitOfWork was still active during the rendering of the View. This meant that any complex lazy loaded queries could still be evaluated which could leave me vulnerable to N+1 problems.
In the end I created a UnitOfWorkAttribute which inherits from ActionFilterAttribute, this enables me to dispose of the current unit of work after the action is completed but before the view is processed. It means that if the view triggers anything that causes database access it throws an error. I can now enforce the convention that all data must be loaded by the action.
A long time ago I wrote a few posts about using "Domain Driven Design"-esque repositories using Linq to SQL ("Domain Driven Design Repositories in Linq to SQL"). I still use that general pattern with a few tweaks with extra layer of a "Unit of Work" to manage context lifetimes. I'm using this rebuild as a chance to play with Entity Framework 4 and so need to implement the appropriate interfaces all over again. The only major functionality change will be bringing in support for Entity Frameworks "Include".
I'm not going to go over the full pattern here, just the new parts for Entity Framework, the IRepository interface has changed that GetAll returns an interface IQuery which is pretty much the IQueryable interface with the Include method.
The implementations for IQuery and IRepository are as follows.
publicclassEntityRepository<T> : IRepository<T>where T : class
{
privatereadonlyObjectSet<T> objectSet;
public EntityRepository(ObjectSet<T> objectSet)
{
this.objectSet = objectSet;
}
publicIQuery<T> GetAll()
{
returnnewEntityQuery<T>(objectSet);
}
publicvoid Save(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.AddObject(entity);
}
publicvoid Update(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.Attach(entity);
}
publicvoid Delete(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.DeleteObject(entity);
}
}
publicclassEntityQuery<T> : IQuery<T>
{
privatereadonlyObjectQuery<T> query;
public EntityQuery(ObjectQuery<T> query)
{
this.query = query;
}
publicIQuery<T> Include(string path)
{
returnnewEntityQuery<T>(query.Include(path));
}
IEnumerator<T>IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)query).GetEnumerator();
}
IEnumeratorIEnumerable.GetEnumerator()
{
return ((IEnumerable)query).GetEnumerator();
}
ExpressionIQueryable.Expression
{
get
{
return ((IQueryable)query).Expression;
}
}
TypeIQueryable.ElementType
{
get
{
return ((IQueryable)query).ElementType;
}
}
IQueryProviderIQueryable.Provider
{
get
{
return ((IQueryable)query).Provider;
}
}
}
The actual Repository that gets used by the domain layer simply delegates all it's work back to a internal repository based off the current unit of work. This is important section because it decouples the domain repository from repository doing the actual work and allows me to change the underlying data source if necessary.
publicclassRepository<T> : IRepository<T>where T : class
{
privatestaticIRepository<T> Current
{
get
{
returnUnitOfWork.Current.CreateRepository<T>();
}
}
publicvirtualIQuery<T> GetAll()
{
return Current.GetAll();
}
publicvirtualvoid Save(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Save(entity);
}
publicvirtualvoid Update(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Update(entity);
}
publicvirtualvoid Delete(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Delete(entity);
}
}
I'll get into the Unit of Work stuff in my next post.
For the new version of the website I'm using the Data Annotations validators for validating view models posted to the controllers. As I'm sure everyone who starts down this road does one of the first things I wanted to create was an EmailAttribute by extending RegularExpressionAttribute. The mighty Scott Gu goes through this process in his blog post on Model Validation. Unfortunately his solution stops just short of everything that's required.
returnString.Format("{0} is an invalid email address", name);
}
}
The EmailAttribute works correctly on the server but doesn't trigger any validation on the client side. What you need to do is inform the DataAnnotationsModelValidatorProvider (phew) that the EmailAttribute acts in exactly the same way as the RegularExpressionAttribute. This can be achieved with this simple bit of code in Application_Start.
A while ago I was looking into dynamic languages (in particular Iron Python) and an idea presented in a talk stuck with me. I wish I could remember who it was to credit them. In essence it was that in dynamic languages unit tests verify what the compiler can't enforce and that we can think of the compiler as simply another unit test in the system. This was obviously framed in a way that meant that the type safety wasn't necessary but lets approach it from a different direction.
Don't unit test what you can use the compiler to enforce.
A common thing I see in MVC examples is a unit testing verifying that some controller action returned the correct type of ActionResult e.g IndexReturnsViewResult. While this test is useful, we can remove it by changing the return type of Index to ViewResult, now the compiler enforces our test for us! This clearly won't work for actions that return different types of result depending on context (this is where unit testing should be testing). But if we can have our compiler enforce some of our specification then I think we should.