Sunday, June 28, 2009 |
|
|
On my recent blog post, I demonstrated that I'd been able to submit the same LINQ query to both an in-memory repository and a L2S Repo. However, after discussing this on StackOverflow, it seems that we must be careful. While I have seen this technique demonstrated in other articles, I've not found anything from an official perspective, so I will probably err on the side of caution with this one. While L2O and L2S may overlap on 90% of cases, that 10% is always going to be the one to bite you when you don't have time to react. So, it's back to a simpler approach. I'm still going to stick with the Repository pattern, but instead of exposing the Repository as IQueryable<T> (even if the underlying source is IEnumerable<T>) I'm going to encapsulate the actual queries within a Fetch(ICriteria) method instead. This worked well for me in a previous application, but it has the obvious drawback that we have to define the queries differently for each Repository implementation. However, it still allows us to abstract our DAL from our Application layer, as shown in this simple diagram:  So we can still use a Domain Driven approach to developing our app, which is great, but we have to ensure that integration testing is thorough when we introduce our other implemented repositories. |
Sunday, June 28, 2009 12:21:14 PM (GMT Standard Time, UTC+00:00) | | Database | TDD
|
|
|
|
Saturday, June 27, 2009 |
|
|
I've started work on a new project recently and the first thing for me to sort out is the Data Access Layer. Because the Repository pattern served me so well in the past, I'm going to start there. However, the previous solution used a bespoke QueryBuilder which converted an ICriteria into the appropriate SQL. This SQL was then just passed through as CommandText on an ADO.NET connection to the appropriate database, Oracle or SQL Server. What we did was to mock the Repository using LINQ to Objects, and this allowed us to construct our application in a Domain-Driven fashion. Great! However, there was always room for improvement. I've wanted to use LINQ as my ORM for quite some time now, and I know the purists out there will say that LINQ isn't an ORM, but for practical purposes in this project it's going to be. Also, I've decided to use L2S rather than the Entity Framework. My mantra is Design For Test, and right now L2E is just not persistent-ignorant in the slightest. There are hacks as I've outlined in previous blog posts, but building hacks into the foundation of your application is a recipe for disaster. While L2S may not be supported in future by MS, who cares?! It works, plenty of good, solid apps have been built on it, AND IF WE GET THINGS RIGHT, there's no reason why we can't switch to L2E v2.0 next year. We can do this because we are going to abstract out the actual DataContext, and access our data using POCO and Repository pattern. In addition, if we can swap out the DataContext, then given that LINQ to Objects and LINQ to SQL queries are the same (or at least I hope they are, more on this later) then we can have a set of queries that we can run on both in-memory and database sources. Truly Datasource-Agnostic. I got the inspiration for this from http://compiledexperience.com/Blog/post/Domain-Driven-Design-Repositories-in-LINQ-to-SQL.aspx - and it works!  This diagram shows the LinqToSQL assembly, but we can also replace the SQLDataSource and SQLUnitOfWork with a MemoryDataSource and MemoryUnitOfWork. For example, if we want to test an in-memory collection, we do the following: MemoryUnitOfWork context = new MemoryUnitOfWork();
Repository<Customer> r = new Repository<Customer>(context);
r.Save(new Customer(1, "Joe Bloggs"));
r.Save(new Customer(2, "Joanna Bloggs"));
IEnumerable<Customer> customers = from c in r.Fetch(null) where c.ID == 1 select c;
List<Customer> results = customers.ToList<Customer>();
Assert.AreEqual("Joe Bloggs", results[0].Name);And if we want to test an actual connection to a database using L2S: DataContext db = new DataContext("Data Source=(local);Initial Catalog=DMGTest;Integrated Security=SSPI");
SqlUnitOfWork context = new SqlUnitOfWork(db);
Repository<Customer> r = new Repository<Customer>(context);
IEnumerable<Customer> customers = from c in r.Fetch(null) where c.ID == 1 select c;
List<Customer> results = customers.ToList<Customer>();
Assert.AreEqual("Joe Bloggs", results[0].Name);Note the line IEnumerable<Customer> customers = from c in r.Fetch(null) where c.ID == 1 select c;
which is identical in both versions. My next step is to encapsulate the queries using the Specification pattern, as Ritesh shows here. So now we have completely isolated our domain from our DAL, and with the introduction of the Specification pattern we can look at our queries from a domain perspective also. The code is just bashed out at the moment, but if you want it then just drop me a line and I'll send it over.
 |
|
|
|
|
Tuesday, May 26, 2009 |
|
|
Javascript, as I'm sure you are aware, has no in-built knowledge of classes, inheritance or interfaces as other OO programming languages do. We have to engineer these using various constructs and work-arounds, in order that we maintain code order and good programming principles. With more and more code on the client-side in order to provide rich user experiences, this is vital or you'll be condemned to snippet hell. Simple View-Controller patternSay you want to implement a bog-standard separation of View-Controller logic. The View is a collection of controls, and directly handles the interaction of these controls before packaging them up and sending them on to the Controller. In the Windows world, we would raise a custom event from the View which the Controller hooks into, but given Javascript's flexible duck-typing, we can bind the View directly to the Controller and inject a Stub in the future for testing if we should wish. Anyway, our View has a button. When the user clicks the button, we want the Controller to know what to do, not the View. The View will have a SetController method, which when set, will bind the button's click event (I've omitted the unbind to clear things up) to the appropriate method on the Controller. Like so: function RefineSearchView() {
var _controller;
}
RefineSearchView.prototype.setRefineSearchController = function(newController) {
this._controller = newController;
$("#btnStreetRefineFilter").bind("click", createMethodReference(this._controller, "HandleFilter"));
}NOTE: this is where it gets interesting. createMethodReference() - what's that all about? Why don't I just do: $("#btnStreetRefineFilter").bind("click", this._controller.HandleFilter);
You could expect this to simply bind the click event on to this particular View's Controller's HandleFilter() method. Non? Non. The reason this won't work is because when we bind the click event, we are not in the correct context. This article - with the suitably majestic title of Object-Oriented Event Listening through Partial Application in JavaScript - will explain it in ways far better than I could! This is to demonstrate in it's most basic format - we can go on as the article suggests, wave our magic refactoring wand until it transforms from the ugly duckling of createMethodReference into the elegant swan of this.element.onclick = this.buttonClicked.bind(this); Controller Handle methodNow we have this set up, it's just a case of implementing our HandleFilter method on the controller: RefineSearchController.prototype.HandleFilter = function(e) {
var searchParams = this._searchController.getSearchParams();
var locality = this._view.getLocality();
var town = this._view.getTown();
searchParams._locality = locality;
searchParams._town = town;
this._searchController.setSearchParams(searchParams);
this._searchController.search();
this._view.updateFilterStatus(searchParams);
}So now we have completely separated our code into View and Logic sections. This example was a bit contrived, but you can imagine the situation where our View has to gather information from a number of controls before wrapping these up and sending them on to the Controller in a nice abstract package, similar to the searchParams outlined above. Not only does this approach give benefits in terms of maintenance, but the stage is now set for unit-testing and programmatically driving your dynamic web page... |
|
|
|
|
Wednesday, May 13, 2009 |
|
|
We had a review of some client-side code today, as it had started to smell a little "off". As always, the indication I use when quickly reviewing a design is - how easy is this to unit test? The problemLogic all over the place. Massive "if" statements. More spaghetti than an episode of the Sopranos. For our web app, we have a number of "tools"; when the user clicks one, it puts the application into that particular tool mode, which means that any subsequent mouse events have to check which mode we are currently in, and take the appropriate action. Not only that, but we have introduced a vector view layer (SVG) so we have some tools that update the image layer, some that update the vector layer, and some that update both. The solutionStick to established patterns. When dealing with UI, everything boils down to MVC in the end.  What we've done here is separate out each tool into an "Interactor" class. The View provides the abstraction of each view type, and also the UI events. The Controller provides the glue to stick everything together. In Summary: - The View knows about the different view types, and knows about UI events.
- The View Types know how to render themselves, but are still pretty "dumb".
- The Controller knows about UI events, and things called Interactors, but it doesn't know what Interactors are or what they actually do.
- The Interactors know exactly what is going on, they interact directly with the view type and the server.
 This solution certainly isn't "pure" by any means - there is no M! And I am in no doubt that we could refine this further. But the main thing is we have separated everything out into distinct, logical components that have a defined and related set of responsibilities. What's more this design is geared for unit testing. We can test the Interactors independently of the views (by dependency injection, which we will do later) and then add another layer of tests integrating the Controller, and so on. |
|
|
|
|
Tuesday, January 06, 2009 |
|
|
It takes a while to get going after the holidays, but once I had dusted the mince pie crumbs from the thinking cap it was business time.
As you may be aware from previous posts, I'm a regular user of the various flavours of the MVC pattern (MVC, MVP, Supervising Presenter etc. I'll just refer to it as MVC from now on, even though the exact pattern I'm using may not be that). The software might take a little longer to construct, but this will pay back in maintainability, testability, legibility and other -bilities.
The task for today was to apply a user-defined 'mask' over a datasource that was bound to a grid. In this specific case, we apply the mask to the grid instead of the datasource, but the principles would be the same if our requirements were to modify the datasource in some way.
We have 3 MVC-triads involved, and the associations between which (and classes) are illustrated below:

The 'Super' triad, shown in green, is where it will begin. The Window will receive the click event to show the Top N dialog, which will notify the WindowController. The WindowController will then create the concrete TopN View (the dialog), passing this into the TopNController.
When the user clicks the 'Apply' button on the Top N dialog, this will communicate the specified values to the TopNController, which will then modify the PivotViewDef. Note: The PivotViewDef is stored by the Document, and bound to the GridView by the GridController on instantiation. We use a simple Observer pattern for this, which means that whenever PivotViewDef is modified, we broadcast this change to any interested parties, which can then take action.
Therefore when the PivotViewDef is modified, it will automatically refresh the GridView.
This is a clean and elegant design, as it removes any logic from the forms. The inter-dependencies between the various components are also limited, which reduces the complexity. And because the TopNController only communicates to the view via an interface, it is inherently unit-testable.
|
Tuesday, January 06, 2009 8:46:42 PM (GMT Standard Time, UTC+00:00) | | c# | Patterns | TDD
|
|
|
|
Wednesday, February 27, 2008 |
|
|
Unit Testing of database applications is a large topic, so I'll concentrate on a specific scenario.
If you have the following setup:
TestFixture
- Init - populate database with default data
- Teardown - run delete script to restore the database to it's previous state.
This will be sufficient if none of our tests modify the data in between. But we'll need to to test Create, Update and Delete methods of our business objects.
So, if one Test updates the database, but another Test is run after it which is expecting the database to be in it's original state (i.e. the state it's in straight after the TestFixture.Init() method has been called) then we have a problem. But we can't determine the order that the tests will run in, so what are our options?
We could partition our tests into different TestFixtures, so avoiding the problem altogether. Or we could run the Populate and Delete scripts after EVERY test - though this is likely to be slow and will probably become impractical as our test library grows.
A good solution would be to have each test run in isolation, where changes to the database are rolled back after each test is run - this way the database can be updated in one test but returned to it's original state before the next test runs.
We can do this by using the TransactionScope object, like so: [Test]
private void TestSomething()
{
using(new TransactionScope())
{
//Update the database
//Perform Assertions
}
}
If we need to do some common initialisation of the TransactionScope object, for example setting IsolationLevel or Timeout properties, then we can wrap this up in a class as follows: public class RollbackTransaction: IDisposable
{
private TransactionScope mScope;
public RollbackTransaction()
{
TransactionOptions tOptions = new TransactionOptions();
tOptions.IsolationLevel = IsolationLevel.RepeatableRead;
tOptions.Timeout = new TimeSpan(2, 0, 0);
mScope = new TransactionScope(TransactionScopeOption.RequiresNew,
tOptions);
}
///<summary>
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///</summary>
///<filterpriority>2</filterpriority>
public void Dispose()
{
mScope.Dispose();
}
}
and instead of using(new TransactionScope()), we would instead have using(new RollbackTransaction()).
|
Wednesday, February 27, 2008 8:00:59 PM (GMT Standard Time, UTC+00:00) | | TDD | Database
|
|
|
|
|
|
|
| Archive |
| July, 2010 (1) |
| June, 2010 (3) |
| May, 2010 (6) |
| April, 2010 (5) |
| March, 2010 (1) |
| February, 2010 (3) |
| January, 2010 (6) |
| December, 2009 (4) |
| November, 2009 (4) |
| October, 2009 (5) |
| September, 2009 (3) |
| August, 2009 (4) |
| July, 2009 (2) |
| June, 2009 (7) |
| May, 2009 (3) |
| April, 2009 (4) |
| March, 2009 (1) |
| February, 2009 (2) |
| January, 2009 (4) |
| December, 2008 (6) |
| November, 2008 (4) |
| October, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (1) |
| March, 2008 (5) |
| February, 2008 (3) |
|
|
|
|