DDD and C# language semantics

This morning I was reading an article about properties vs attributes by Eric Lippert, one of the designers of the C# language. In it, he explained:

Properties and fields and interfaces and classes and whatnot are part of the model; each one of those things should represent something in the model world. If a property of a “rule” is its “description” then there should be something in the model that you’re implementing which represents this. We have invented properties specifically to model the “an x has the property y” relationship, so use them.

That’s not at all what attributes are for. Think about a typical usage of attributes:

[Obsolete][Serializable]public class Giraffe : Animal{ ...

Attributes typically do not have anything to do with the semantics of the thing being modeled. Attributes are facts about the mechanisms – the classes and fields and formal parameters and whatnot. Clearly this does not mean “a giraffe has an obsolete and a serializable.” This also does not mean that giraffes are obsolete or serializable. That doesn’t make any sense. This says that the class named Giraffe is obsolete and the class named Giraffe is serializable.

Now he doesn’t explicitly mention domain-driven design, but I think it’s an important point for .NET developers who’re trying to get into it: attributes are only for implementation details – don’t use them for domain model concepts.

Keep track of your Internet browsing at work with 8aweek

According to a survey conducted last year, the average employee fritters away eight hours a week on non work-related activities. Personal Internet browsing was cited as the number one culprit; I know I’m a little bit guilty of it, too. Leaving my personal e-mail open all day (and stopping to read new messages as they arrive) is something particularly I’m particularly bad at.

This week I discovered 8aweek, a handy Firefox plugin designed to help you reclaim some of this time, by monitoring non-work related browsing. 8aweek installs as a toolbar (which, thankfully supports FireFox customization so you can move the buttons around), and maintains a no-registration-required profile on their website. You set up a bunch of restricted sites that you want to limit access to, and a daily quota for the total amount of time you can spend browsing them (the default is half an hour).

When you exceed this quota, you get a nice warning message in the middle of your browser window:

Your restricted browsing time is up

Whether you obey it’s restrictions, or just keep clicking “10 more minutes”, is another question, but at least being made aware of the issue is helpful. After all, guilt is a great motivator.

I’ve been using it for a couple of days and I already feel like I’ve been more productive at work. Plus, it’s nice to be able to keep on top of this stuff yourself, rather than having limits imposed on you by your employer. 8aweek also gives you a nice visualisation of your browsing habits, and even grades you on your behaviour (I’m all Cs at the moment).

Domain entities vs presentation model objects, part 2: mapping

Domain entities vs presentation model objects, part 2: mapping

This is the second half of a two-part article. Read the first half here: Domain entities vs presentation model objects.

In my last post, I wrote about the difference between domain entities and presentation model objects. Remember my two task classes — the transactional domain entity and the UI presentation object? They’re very similar, and this could lead to a lot of ugly hand-written plumbing code mapping fields on one to the other.

// Task domain entity.public class Task{    public int Id;    public string Name;    public DateTime? DueDate;    // ...etc.}// Task presentation model object.public class TaskView{    public int Id;    public string Name;    public string DueDate;    public bool IsUnscheduled;    public bool IsOverDue;    public long SortIndex;}

Instead, I’m using an open-source .NET library called AutoMapper by Jimmy Bogard — an object-object mapper (OOM) that sets values from one type to another.

Setting up a map from one type to another is dead simple — AutoMapper will automatically match fields with the same name. For other stuff we use lambda expressions, or delegate to another class. Here’s what my Task-to-TaskView mapping looks like:

// Set up a map between Task and TaskView. Note fields with the same names are// mapped automagically!Mapper.CreateMap<Task, TaskView>()    .ForMember(dest => dest.DueDate, opt => opt.AddFormatter<DueDateFormatter>())    .ForMember(dest => dest.SortIndex, opt => opt.ResolveUsing<SortIndexResolver>());

That was easy! Note I’m using a custom value formatter for the DueDate:

public class DueDateFormatter : IValueFormatter{    public string FormatValue(ResolutionContext context)    {        DateTime? d = context.SourceValue as DateTime?;        if (d.HasValue)            return d.Value.ToString("dddd MMM d");        else            return "Anytime";    }}

…and a custom resolver for the sort index (an integer derived from the task’s due date). Note that, while a formatter transforms one field by itself; a resolver examines the whole object to derive a value:

public class SortIndexResolver : IValueResolver{    public ResolutionResult Resolve(ResolutionResult source)    {        Task t = source.Value as Task;        DateTime sortDate = t.DueDate.HasValue ?            t.DueDate.Value : DateTime.MaxValue;        long sortIndex =             Convert.ToInt64(new TimeSpan(sortDate.Ticks).TotalSeconds);        return new ResolutionResult(sortIndex);    }}

With dedicated classes for formatting and resolving values, tests become very easy to write (although I did write my own ShouldFormatValueAs() test helper extension method):

[TestFixture]public class When_displaying_a_due_date{    [Test]    public void Should_display_null_values_as_anytime()    {         new DueDateFormatter().ShouldFormatValueAs<DateTime?>(null, "Anytime");    }    [Test]    public void Should_format_date()    {        new DueDateFormatter().ShouldFormatValueAs<DateTime?>(                new DateTime(2009, 02, 28), "Saturday Feb 28");    }}

Putting it to practice, it becomes a one-liner to create a new TaskView instance given a Task.

// Grab a Task from the repository, and map it to a new TaskView instance.Task task = this.tasks.GetById(...);TaskView taskView = Mapper.Map<Task, TaskView>(task);

Awesome!

How to Lose Traction on a Personal Software Project

So you’ve started writing your first program — great stuff! The software development can be very tricky, especially if you are not absolutely sure what you are doing. In this blog we are exploring different software development methodologies. Here are a few tips and traps to watch out for along the way.

Long periods of time when your program doesn’t compile and/or run at all

You enthusiastically start work on some big changes (e.g. re-architecting your application), but stop because you hit a brick wall, or don’t have the time to finish it. The source code is left in a crippled and unfinished state. You can’t do anything with any of your code until this is fixed, and the longer you leave it, the more you’ll forget and the harder it will be to get started again.

In Continuous Integration this is called a broken build, and is a big no-no because it impacts other peoples ability to work. Without the pressure of a team environment pushing you forward, having a roadblock like this in your path makes it very easy to lose faith and motivation.

Make massive changes on a whim without revision control or a backup

There’s nothing worse than changing your mind about the design of something after you’ve already thrown away the old one. When you do something that involves changing or deleting existing code, be sure to make some sort of backup in case things don’t work out.

If you haven’t taken the plunge with revision control yet, I highly recommend looking at some of the free SVN or GIT hosting services out there — once you get into it, you’ll never look back.

Ignore the YAGNI principle and focus on the fun/easy bits

Focusing on things like validation, eye candy or even general purpose ‘utility’ functions is a great way to build up a large complex code base that doesn’t do anything useful yet. Focus on the core functionality of your software first — your main features should be complete before you start thinking about nice-to-haves.

Throw your code away and start from scratch

As Netscape famously discovered a few years ago, throwing away existing code to start afresh is almost never a good idea. Resist the urge and make a series of small, manageable code refactorings instead.

Start programming before you have a clear goal in mind

Instead of a command line tool, maybe my application would be better as a simple GUI application? Or, I was originally writing my homebrew game for my old Xbox360, but now that we’ve bought a Wii, I’ll port it to that instead!

What are you actually trying to achieve? Spend some time with a pen and some paper coming up with a really clear vision of what you’re trying to create — e.g. screen mock-ups. If you don’t know what you’re writing from the start, the goal posts will keep moving as you change your mind, and you’ll have no chance of finishing it.

Get carried away with project hype before you’ve actually got anything to show for yourself

Spending hours trying to think of the perfect name for your software, designing an icon, choosing the perfect open-source license and making a website won’t get you any closer to having a working application. Get something up and running first, and worry about telling people about it later.

Start a million new features and don’t finish any of them

Jumping from one idea to another without finishing anything is like spinning a car’s wheels and not going anywhere. Make a list of features your program should have, and put them in order of most-to-least important. Work on them, one-at-a-time, in that order.

Deployment and source-control-friendly database versioning scripts

One of the projects I’m on has over 2,200 stored procedures. Until I arrived, none of these were under source control — the ‘stable’ version was whatever was on the production database server, and the ‘trunk’ version was whatever was in the development database server (which incidentally wasn’t even backed up).

Anyway, I set about exporting all the stored procedures and checking them into source control. But as easy as it sounds, it actually took a few goes to get the it all right. You see, when generating a CREATE script with IF NOT EXISTS, SQL Management Studio has a habit of generating entire scripts as one giant EXEC sp_executesql string instead of just putting a GO in between. This isn’t very good for development — you don’t get intellisense, syntax highlighting, etc inside a string.

To get around this problem, I ended up generating two separate scripts — first a DROP (with IF NOT EXISTS), then a CREATE (without it) — and set SSMS to put each in the same file (Append to File). This gave me one script per stored procedure, each with an IF EXISTS DROP, GO then CREATE statement — perfect for source control.

Here are some other tips for configuring SQL Management Studio (via Options > SQL Server Object Explorer > Scripting) to make it automatically generate friendly scripts:

  • Disable Include descriptive headers. They sound helpful, but all they do is add the script date and repeat the object’s name. This is really annoying because it clutters up my results for source-code text search in Visual Studio.
  • Disable Script USE <database>. We often have several copies of the same database running with different names on the same SQL box (e.g. for different development branches). Hard-coding the name of the database in all your scripts means you have to manually change all the USE statements every time you run them. And trust me — the risk of having your changes leak over and get applied to the wrong database is not really something you want to be worrying about.
  • Enable Include IF NOT EXISTS clause. Stored procedures, triggers, functions — it’s much easier to just nuke and re-create them every time instead of worrying about the semantics of CREATE vs ALTER. This also means you can just run each script over and over and over again.

If you get it right, SQL Management Studio 2008’s Script DROP and CREATE should produce something that looks like:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_Employee_Get]') AND type in (N'P', N'PC'))DROP PROCEDURE [dbo].[usp_Employee_Get]GOCREATE PROCEDURE [dbo].[usp_Employee_Get]AS        SELECT                EmployeeID,                FirstName,                LastName        FROM                EmployeeGO

We also put permissions (e.g. GRANT EXEC) at the end of each script, so they are restored each time the stored procedure is created.

Automatically log all INSERT, UPDATE and DELETE commands on a table in SQL Server

Just before Christmas we had a problem with an application database where rows were being mysteriously deleted. Unfortunately the table in question is written to by 20-30 stored procedures, so there was no single point in the application where I could put a trace.

Instead, I wrote a quick generic script that would automatically create the necessary triggers to log all INSERT, UPDATE and DELETE commands on a table of your choosing (or just generate the script).

For example, every time someone modified data in the HR.Employees table, a row would be written to HR._Employees_Audit with all the new values, time stamp, command, and name of the user who did it.

You can download it here: sql-server-auto-audit.sql

Refactoring insight: should I really have a separate domain service for that, or is it the responsibility of an existing entity?

This insight follows on from an earlier article where I identified that the business rule “when an employee leaves the organisation, all their assets must be returned” was part of the domain model, and not just a matter of cleaning up foreign keys in the database.

I originally implemented this rule as part of a dedicated domain service called IPersonTerminatorService. Later on, I refactored it out into a standalone IAssetReturnerService to satisfy the single-responsibility principle.

asset-returner-service

But this morning I realised something: in real life, it’s the employee himself who returns all his stuff — not some other process. By taking this responsibility away from the Employee class I’ve committed two sins: creating a fictional concept in the domain, and reducing the capabilities of the Employee (leading to an anemic data-only domain model).

Time to give this responsibility back to the employee:

employee

Capture the Output from a Scheduled Task

Today I had to diagnose a problem with a Windows Scheduled Task that was sporadically failing with a non-zero return code. The exe in question was a .NET console application that was throwing an exception before Main() got called; it was outside our try-catch block.

Anyway, if you ran the .exe from a command line yourself, you would see the error written to stderr. If you ran the Scheduled Task, the error was not logged anywhere.

To capture the output of the scheduled task, I redirected it to a text file with the following command:

1
2
3
before: NightlyBatchJob.exe
after: cmd /C NightlyBatchJob.exe >> NightlyBatchJob.output.txt 2>&1

The > symbol redirects the output to a file; >> makes it append instead of creating a new blank file each time it runs. 2>&1 makes it include the output from stderr with stdout — without it you won’t see any errors in your logs.

The whole command is run in a new cmd.exe instance, because just running an .exe directly from a scheduled task doesn’t seem to produce any console output at all. For more posts on this subject, go back to the homepage.

Refactoring insight: repositories gone wild!

Here’s a snippet from my prototype NHibernateRepository<T> I mentioned the other day. Can you see what I’ve done wrong here?

public abstract class NHibernateRepository<T>{    protected ISession unitOfWork;    protected IEntityValidator<T> validator;    protected NHibernateRepository(ISession unitOfWork,        IEntityValidator<T> validator)    {        if (unitOfWork == null)            throw new ArgumentNullException("unitOfWork");        if (validator == null)            throw new ArgumentNullException("validator");        this.validator = validator;        this.unitOfWork = unitOfWork;    }        protected virtual void Validate(T item)    {        IEnumerable<RuleViolation> ruleViolations =             this.validator.GetAllRuleViolations(item);        if (ruleViolations.Count() == 0)            return;        string message = String.Format(            "The {0} '{1}' could not be persisted because it failed validation.",            typeof(T).Name, item);        throw new RuleViolationException(message, ruleViolations);    }        public virtual void Save(T item)    {        Validate(item);        using (ITransaction transaction = this.unitOfWork.BeginTransaction())        {            this.unitOfWork.SaveOrUpdate(item);            transaction.Commit();        }    }    // ...}

See that Validate() method? It’s very clever, automatically checking entities are valid before it commits them to the database. Unfortunately, validating entities is not the responsibility of a repository. This is a big fat violation of the single responsibility principle (SRP), and should be moved to a higher-level domain service instead.

Refactoring insight: simple foreign key cleanup or a domain service?

On my quest for DDD/TDD nirvana, I’m going to start documenting moments of insight on real projects when design problems are solved, principles suddenly make sense for the first time, or pitfalls are avoided. I want to do it partly for posterity, and partly to help others who are also learning. Here’s the first one.

One of my projects at the moment is developing a simple asset management system. It’s basically just a catalog of assets (computers, devices and office furniture) with various details (specs, serial numbers, notes on wear and tear etc). Each asset may be issued to a person.

I was writing some tests for my concrete repositories (mainly in order to check the database mappings are correct), when the question arose: what should happen to a person’s assets when the person is deleted?

My first thought was simply to edit the mapping XML and change a cascade option so Asset.AssignedToPersonID would be set back to NULL. However, I realised this is more than just a foreign key issue for NHibernate — returning a person’s assets when they leave the organisation is a significant domain concern.

If I take the shortcut and leave it implemented as a cascade option:

  • It’ll work fine, but the business rule will be implicit, rather than explicitly expressed somewhere as something that happens when a person is terminated. Other developers probably won’t even notice it at all.
  • The implementation won’t be testable without hitting a live SQL instance.
  • The business rule won’t be observable in other test cases unless they hit a live SQL instance, because mock repositories will likely not factor for it.
  • If we ever move away from NHibernate, or otherwise need to recreate the database mappings, this feature could be lost, and will probably only be rediscovered after FK constraint errors arise.

That’s no good. Let’s make this business rule an official part of the domain model instead, with a fully-fledged domain service:

public interface IPersonTerminatorService{    void TerminatePerson(Person person);}public class PersonTerminatorService : IPersonTerminatorService{    IPersonRepository personRepository;    IAssetRepository assetRepository;    public PersonTerminatorService(IPersonRepository personRepository,        IAssetRepository assetRepository)    {        DesignByContract.Require(personRepository != null,             "personRepository cannot be null.");        DesignByContract.Require(assetRepository != null,            "assetRepository cannot be null.");                this.personRepository = personRepository;        this.assetRepository = assetRepository;    }    public void TerminatePerson(Person person)    {        ReturnAllAssetsIssuedToPerson(person);        this.personRepository.Remove(person);    }    public void ReturnAllAssetsIssuedToPerson(Person person)    {        IEnumerable<Asset> assets =             this.assetRepository.GetAssetsIssuedToPerson(person);        foreach (Asset asset in assets)        {            asset.Return();            this.assetRepository.Save(asset);        }    }}

The implementation is not tested yet (and will likely be refactored later because I think it does too much stuff) but here’s what it’s going to satisfy:

[Test]public void Terminating_a_person_returns_all_assets_issued_to_them(){    Asset a = new Computer() { Name = "Apple Powerbook" };    Asset b = new Computer() { Name = "Dell Dimension" };    Asset c = new Computer() { Name = "IBM ThinkPad" };    Person p = new Person("Richard");    a.IssueTo(p);    b.IssueTo(p);    c.IssueTo(p);    IPersonTerminatorService terminatorService =        ServiceLocator.Current.GetInstance<IPersonTerminatorService>();    terminatorService.TerminatePerson(p);    Assert.IsNull(a.IssuedTo);    Assert.IsNull(b.IssuedTo);    Assert.IsNull(c.IssuedTo);}

It’s a start!