Wednesday, June 24, 2009

Exploring a WPF Business Application Architecture 3

It's time to add some DDD style repositories to the pet shop sample's domain model. While I don't want to go down the one-IRepository-fits-all route, I do want to reuse code between the specific repositories. In this post I'll show how to do that using interfaces and extension methods in conjunction to create repository traits that can be mixed and matched to implement specific repositories.

One Size Does Not Fit All
As argued in a nice blog post by Richard Dingwall a one size fits all approach along the lines of:










is not going to work out well: Some of the methods in the one-size-fits-all interface might be inappropriate for some domain classes. So what do we do? -We introduce a number of interfaces each representing specific traits of a repository.

Traits
As proposed by Mr. Dingwall we create a number of interface each specifying one specific trait that a repository might have. Like these:
























and probably others. Now that enables us to pick and choose which traits a specific repository should have. For instance a repository for the pet shops category objects would probably need all the traits listed above, hence it implements all those interfaces:








Incidentally implementing each of these traits is made really easy by Castle.ActiveRecord. All the smae I still don't want to implement them in each and every of the concrete repositories where they are used. This is where extension methods comes in.

Mixins
To be able to provide reusable implementations of the traits I implement an extension method for each method on the trait interfaces:

public static class ActiveRecordRepositoryImpl
{
internal static IEnumerable<Entity> GetAllImpl<Entity>(this ICanGetAll<Entity> self)
where Entity : class
{
return ActiveRecordMediator<Entity>.FindAll();
}

internal static Entity GetByIdImpl<Entity, Key>(this ICanGetById<Entity, Key> self, Key id)
where Entity : class
{
return ActiveRecordMediator<Entity>.FindByPrimaryKey(id);
}

internal static void RemoveImpl<Entity>(this ICanRemove<Entity> self, Entity entity)
where Entity : class
{
ActiveRecordMediator<Entity>.Delete(entity);
}

internal static void SaveImpl<Entity>(this ICanSave<Entity> self, Entity entity)
where Entity : class
{
ActiveRecordMediator<Entity>.Save(entity);
}

internal static int GetCountImpl<Entity>(this ICanGetCount<Entity> self)
where Entity : class
{
return ActiveRecordMediator<Entity>.Count();
}
}
Notice how easy Castle.ActiveRecord makes this. That's nice.
Right; then these *Impl extension methods are used in the concrete repositories:

public class CategoryRepository :
  ICanGetAll<Category>,
ICanGetById<Category, int>,
ICanGetCount<Category>,
ICanRemove<Category>,
ICanSave<Category>
{
public IEnumerable<Category> GetAll()
{
return this.GetAllImpl();
}
public Category GetById(int id)
{
return this.GetByIdImpl(id);
}
public int GetCount()
{
return this.GetCountImpl();
}

public void Remove(Category entity)
{
this.RemoveImpl(entity);
}

public void Save(Category entity)
{
this.SaveImpl(entity);
}
}

And that's it.

So there still the duplication of calling *Impl methods in each concrete implementation method, but the methods actually implementing the repository traits are shared. I think that's pretty nice.

Monday, June 15, 2009

Exploring a WPF Business Application Architecture 2

In my last post I started writing about a pet shop sample I'm putting together to try out a few ideas about structuring business apps using WPF. In this post I'll show the domain model, and I'll show how it's persisted using Castle.ActiveRecord.

The Model
The domain model of the pet shop is shown here:

It's a straight port of the model used in the pet store iBatis.NET sample. I wont go through the model, but just say that it's complicated enough to be interesting as a sample, while simple and small enough to be quick to implement.
For now the domain classes have no behaviour. It's an anemic model. I expect to add behaviour as needed over time.

The Persistence
To exemplify how the model is persisted using Castle.ActiveRecord, I'll show the code of one of the central entities: The category class.











This is a pure POCO, which I think is nice, but ActiveRecord cannot persist instances of category. To make ActiveRecord aware if this a simple attribute is added to the class:





This means that ActiveRecord will be able to create a Category table in the underlying database, but the framework doesn't know which columns the table should have. We tell ActiveRecord what should actually be persisted to the database by adding a few extra attributes:
















All the C# properties that I want to be persisted to the category database table now has an attribute: Simple cases just have a Property attribute and ActiveRecord figures out the rest. The IList is persisted using a HasMany attribute, which means that the product table records will have a foreign key pointing back to the category table. For this to work the product class needs to be an ActiveRecord too.
Lastly notice the Validate* attributes which tells active record to validate certain things before even trying to save the entity to the database.
That's all that is needed to enable the ActiveRecordMediator class to work on my entities. The mediator can now create, read, update, and delete entities/records in the database.

The complete model can be downloaded from here.

Why Use ActiveRecord?
Firstly: It's so easy. There is really not a lot more to it than what I showed above.

Secondly: It's build on the rock solid basis of NHibernate.

Thirdly: The active record pattern is easy to use, easy to understand and actually suits a lot of situation. On the other hand the fact that you follow that one pattern is also the main limitation.

Fourthly: Entities are still almost POCOs. They've just had a few attributes added. This means they are still easily testable, and that I still hjave full control over my inheritance hierarchy. On the other hand the enitities now do two things: They represent a domain concept, and they declare how they are persisted. That's not full-fledged single responsibility. In the cases I have in mind for this exploration though I can live with that.

What's next?
In the next post I'll write about how to read and save ActiveRecord entities through DDD style repositories.

Tuesday, June 9, 2009

Exploring a WPF Business Application Architecture 1

I've been spending some time looking into how to easily build WPF based line-of-business applications lately. To illustrate my thoughts on that subject I'll put together a sample based on the time honored Java Pet store. In this post I'll write a bit about the type of application I'm aiming for, the pet shop, and the architecture I'm aiming for. In a series of following posts I'll show how the domain model, the persistence, the presentation and so on are coded.

So, I'm not trying to figure out how every WPF app should be architected. Far from it. I'm trying to figure out a default architecture for moderately sized business applications. I.e. apps that: Use WPF for presentation, use an SQL Server database for persistence, runs on an intranet, has in the order 100 - 200 unique users, has moderate to large amounts of data (not huge, though), and no special security issues.

To illustrate I'll use a pet shop: The users can browse through categories of pets, put them in their shopping cart, and eventually check out and pay for the pets.

The plan is to use the MVVM pattern which is a variation on MVC, that focuses on allowing for use of WPF's 2-way data binding while still allowing for separation of concerns. The domain model is nicely separated from the view by the view model, which adapts the data in the domain model to the needs of the view. The presentation logic is pulled out of the code behind files to keep it separated from the view itself. All-in-all MVVM delivers a nice structure that allows for good testability and maintainability. To implement this part I might use Caliburn or PRISM or I might do it by hand. I haven't decided yet.
For the persistence of the domain model to the database I'll use Castle.ActiveRecord which is build around Fowler's Active Record pattern: Each domain object is responsible for its own persistence. Each domain class maps to a database table and has CRUD operations. Each domain object corresponds to a database row. Castle.ActiveRecord makes it really easy to use the Active Record pattern: You just have to add a few attributes to the domain classes and their persisted fields and off you go. Your domain objects are still POCOs except for the attributes, so you get to keep your domain object clean and almost-free of infrastructure.
Lastly I plan to throw in Castle.Windsor for dependency injection.

That's it for now. Next post will be about the pet shop's domain model, and about persisting it through ActiveRecord.