Some thoughts on writing a distributed application
I'm currently on a team writing a fairly large distributed application and (since we're in the Microsoft division at Datacom), we're using an MS stack - specifically WCF to publish the back-end services, and WPF for a thick client.
One of the annoyances about the code-base is the amount of fairly valueless plumbing code we have to write to implement something all up and down the stack. I'm going to go through a contrived (but simple) use case, and describe how we currently implement the solution. Next time I'll talk about using a subtly different design pattern to vastly simplify the process:
Use Case: Customers will be categorised into 'Bronze', 'Silver' and 'Gold'. We want to be able to find the customers by this new category.
So let's start at the bottom of the stack:
Firstly, we need to add a new column to our database 'Customer' table, called 'Category' and update the object model in the ORM (we're using Lightspeed). Lightspeed will generate the DTOs used for transporting data in and out of the database, and these DTOs double as our server-side model.
Next we add a method to the Customer repository interface
like this
public interface ICustomerRepository
{
// you'd probably create a CategoryCode enum, but string will do for this example
IEnumerable<Customer> GetByCategory(string category);
}
and implement the method in our repository. So far so groovy...
Now we need to update the server-side manager class to include the
GetByCategorymethod that calls through to the repository (we use an IoC container to inject the repository into the manager). This is the place where we prepare the query to pass through to the repository, applying any business rules we have before and/or after the call.Next step is to add the method into the service itself. The service calls through into the manager - again, we use IoC to inject the manager into the service.
Now, this is all fairly standard stuff so far, although it is debatable as to the value of splitting out the 'Manager' layer from the service itself...
So with the server-side done, we move onto the client:
First and foremost, we update the service reference thereby regenerating the proxy classes that will be used to send data in and out of the server. So now, we have a client-side copy of the server-side model, but this doesn't match the client-side model. We keep different domain models in the client and the server, and we'll come back to this important part later.
So, we update the client-side model to reflect the changes in the server-side model, so that our mapping code remains intact.
Now, we create the method in the client-side manager. This is the layer that holds the reference to the WCF service and invokes the method over the wire. It maps the results from proxy objects to client-side model objects.
Next (and we're nearly there!) we update the ViewModel to include a call into the (client-side) manager, and finally
We create the controls in the View - textboxes, buttons, etc - and associated Bindings to present the option to the user.
Now, I don't know about you, but I think there's quite a lot of donkey-work going on there, and we can definitely work quite a lot smarter to achieve the same results...


Comments