Saturday, September 30, 2006

AOP

One thing that interests me a lot is AOP, I can definitely see the benefits but so far I haven't had time to try it out.
Has anyone out there used it successfully on a real project and how did it affect the complexity of the codebase and performance?

So far I haven't had a good reason to try something like Spring.NET out but I'm hopeful that I will soon. I'm also looking foward to the Aspect Oriented Refactoring book

One project that also looks interesting is:

http://dotspect.tigris.org/

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Thursday, September 28, 2006

Mini-Microsoft

If, like me, you've never heard of Mini-Microsoft then you might find this blog entry very interesting.

I'd always, naively, believed Microsoft would be a great place to work...maybe not.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

TypeMock - Designing For Testability

A while back I posted on the reasons I thought TypeMock was so useful, namely because I thought decoupling your classes to allow mock instances in wasn't a good way to design. Anyway Roy Osherove now has links to interesting posts on the topic in this blog entry.

I must say I'm still not sold on the idea that designing for test is the right way to decouple your classes in ways that are useful.

Since most of the unit testing is going to be of the domain layer let me explain my views on why TypeMock helps there.

Lets say that I want my domain layer has to call out to infrastructure code. My first thought would be is that really a good idea? If it is then I want to decouple my domain from the infrastructure as much as possible. So in that situation an interface/dependency injection might be the way to go and you might do that during testing.

However I've found that when I want to do real unit testing I'll want to mock quite a few different classes that are depended on and in many cases the depended on classes are also in the domain layer. In those situations interfaces/factories seem overkill, in fact if I put them in I'm just over-complicating things. Thats when I use TypeMock.

Another thing I've realised is that these I only do state based unit testing and have given up on the interaction based unit testing that mocking (and things like TypeMock/NMock) support. I guess I should rethink that.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, September 27, 2006

NHibernate + Generics = Explained a bit better

A friend of mine pointed out my post on "NHibernate + Generics = Small Codebase" was a bit vague so I've added this which might clarify.

What I was trying to say was that combining generics with NHibernate makes writing and testing persistence code very easy. For example here's some code that could save a persistent class using NHibernate.

   Session.Save(toSave);

You want that code to be somewhere outside your domain objects, Evans says to put them in classes called Repositories. You'd have at least one repository per aggregate root, so you are going to end up with quite a few of them.

A base class thus makes sense as all the repositories have a lot of behavior in common. However you want type safety on the methods so putting this in the base class just doesn't cut it:

   public virtual void Save(object toSave)

The solution is obvious, you just use generics with a repository base class:

   public sealed class MyRootRepository : NHibernateRepository<TMyRoot, int>
   {
      .... custom code including extra queries ...
   }

The base class can thus use the type of object its persisting (MyRoot here) and the type of ID field (int here) when it needs it.

I think there is also a big advantage when using generics for persistence testing. For example we have specific tests we want to do for all aggregate roots including concurrency/update/save. We want to do the tests to check the database AND the mapping files are correct but we write the same code each time so we use inheritance from a generic base class:

   [TestClass]
public sealed class MyRootPersistenceTests : AggregateRootPersistenceTestBase<Myroot, int>
   {

      [TestMethod]
      public void CanPersist()
      {
         TestPersistence();
      }

      [TestMethod]
      public void CanUpdate()
      {
         TestUpdate();
      }

      [TestMethod]
      [ExpectedException(typeof(StaleObjectStateException))]
      public void CanHandleConcurrency()
      {
         TestConcurrency();
      }

      # region Overridden Members

      protected override MyRoot CreateAggregateRoot()
      {
         // create and return a MyRoot
      }

      protected override void ModifyAggregateRoot(MyRoot original)
      {
         // modify original
      }

      # endregion
   }


We have similar base classes for a few other situations (non-root aggregate parts, read-only reference data). In each case the vast majority of the code is in the base classes (or other classes they call) and we just use the template method pattern by calling into the abstract members (such as CreateAggregateRoot).

Note that the base class can create an instance of the repository, because we decided to make our NHibernateRepository concrete. In addition the whole thing works because we've written an ObjectComparer class that uses reflection to compare the property values of two instances of a type. The TestPersistence in the base class thus boils down to:

  1. Get the object by calling CreateAggregateRoot
  2. Save the object to the database
  3. Reload the object from the database
  4. Use the ObjectComparer to compare the original and reloaded objects.

Unfortunately each test class must have the test methods (CanHandleConcurrency etc) because although NUnit let you have test methods on a base class VSTS doesn't. Drat.

Anyway this has proved to be very useful and has definitely been a big time saver as we've been moving code across to using NHibernate. I've found my current working style is:

  1. Use TDD to develop the new feature.
  2. If the new feature involved the addition of new fields that need to be persisted then run the persistence tests.
  3. The persistence tests should now fail because when we reload the object and pass it to ObjectComparer it will find that the original object had a value in the new field/property whilst the reloaded object will have the default value.
  4. Add the appropriate content to the mapping file so that the new field is persisted.
  5. Run the tests and they should now pass.

Oh and ignore the repository base class name and the method names, we have reasons for keeping them that way the minute.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Friday, September 08, 2006

Team System

I finally got round to reading this blog entry about the whole Mort/Elvis/Einstein thing. I must admit I'm not overly worried about Microsoft using the personas but I do agree that Rockfords article is slightly questionable.

Anyway one thing that definitely chimed with me was part way down:

There's not much value in taking customer feedback if you stop acting on it. Microsoft’s addiction to waterfall planning practices have sent a strong message to customers regarding Microsoft’s responsiveness late in waterfall development phases. Antiquated project and product management practices are hurting the perception that Microsoft is really interested in feedback. You’ve gotta be continuously responsive all the time, not just early in the game. Maybe if there was some effort to “scrum” a service release earlier than mid-2006 the product feedback center would still have the same credibility it did during the pre- and early Whidbey betas.

I couldn't agree with this more, I've been using Team System for 3 months now and two things have surprised me.

Quality
I'm not a Microsoft basher, in fact I've always been impressed they can release large scale software projects that are of a high quality. I am also happy to forgive an application for the odd crash or the odd problem. However Team System is without doubt the worst Microsoft application I have ever used. It comes down to quality, which I'll discuss later, and the fact that some of the features seem to me to be badly thought out or are very incomplete.

Its not even one area but large swathes of the features that have problems including source control, check in policies, unit testing and code analysis. In many cases they're hard to use, seem to be badly thought and are quite buggy. Here's some of the issues I seem to end up dealing with:

  1. Some files will not be checked in because I moved/renamed/did something else to the folder they were.

  2. The unit tests will fail/abort. There seem to be many reasons for this, I should really start taking screenshots and just reporting them to Microsoft even though I don't have steps to repro.

  3. I won't be allowed to check in because it wants me to run deleted tests.

  4. The code coverage will run but not report the issues as stopping me checking in.

  5. The code coverage will fail with a stack overflow exception (I had to switch off CA2214 because of that little bug, how much fun do you think I had working out it was that exact rule :))

  6. My pending changes area will show up as empty forcing me to restart.

  7. Visual Studio regularly crashes (often when I'm undoing source control check outs), in some cases it offers to send Microsoft information but in most cases even this doesn't happen.

I've reported some of these issues but some are so intermittent and bizarre that I haven't gotten round to it yet, however I'd say that on average I'm hit by atleast 1-3 crashes a week and two of the other issues per day and I know that the developer I work most closely with is also having similiar problems.

Customer Feedback
Like a lot of people I've used NUnit, FXCop, Resharper so when I came to Team System I was very excited. However as I tried to use the refactoring, unit testing, code analysis, class designer and so on I began to find a lot of limitations. What amazed me was that many of these limitations were reported to Microsoft quite some time ago. For example here's three of the issues that bug me:

Unit Testing Inheritance

Class Designer Displaying Dependencies

Compile Time Code Injection

What links these items is that the last replies from Microsoft to them are in 2005 or earlier! For all I know Microsoft are investigating and fixing these issues, for all I know they're being ignored and thats problem...there's no 2 way information sharing going on.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Monday, September 04, 2006

Rolling Back After Database Tests - TransactionScope

For a while now I've been using Roy Osherove's data rollback attribute to ensure that integration tests against the database clear up after themselves.

Unfortunately I ended up having to give up on it because in the move to using .NET 2 and NHibernate I introduced a base class that all our persistence test classes should inherit from. It had the majority of the code needed to do persist/update/concurrency unit tests and was a big time saver. Unfortunately the class used generics, since generics and ContextBoundObjects are a big no-no (see this article) and since the data roll back attribute relied on you (indirectly) deriving from ContextBoundObject I needed to look elsewhere.

In the end I chose to use a TransactionScope, I create it in the test initialize and Dispose of it in the test cleanup method. It seems to work OK though I've occassionally had odd DTC related errors which is a slightly worrying!

Equally annoying is that my test base class idea falls down slightly as VSTS doesn't allow you to put tests in a base class (as described in this feedback item). This means that although I can put the majority of the test code in the base class I need to actually define the tests in the derived class, the tests then call back to the base class which will then call to abstract methods implemented in the derived class (normal template method pattern). What a mess :)

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone