Sunday, March 13, 2011

A thing I just discovered about typing in C#

Let's see if I can type a coherent post about what I think I just learned.

You have some hierarchy of classes:

class Foo {}
class Bar : Foo {}

Then you have some method that takes the base class but wants to know actual type of the object passed in:

class Baz
{
    static void DoStuff(Foo someObject)
    {
        Console.WriteLine(someObject.GetType());
    }
}

...

Baz.DoStuff(new Bar());


Will output:

Foo

I guess I've been out of the static language game for too long because I would've expected that to print out the name of the class passed in at runtime (in this case, Bar). Apparently it doesn't work that way. Probably has something to do with C# being a static language. I don't know, I'm not a compiler designer.

I got it to do what I wanted with generics:

static void DoStuff(T someObject) where T : Foo
{
    Console.WriteLine(someObject.GetType());
}

This will output Bar as expected. It also gives me a reason to use generics when previously I was scratching my head and wondering "Why wouldn't you just call GetType() on the object passed in?" Well THAT's why, STUPID. God.

Tuesday, March 8, 2011

DELIRIOUS AIRPORT CODING

Sitting in an airport after two physically tiring days (my days are usually mentally tiring and spent safely behind the confines of my trusty desk) and I find it very difficult to put together a coherent thought. That last sentence proves it. But that sure doesn't stop me from trying to code. Results are poor. Progress is slow. Automated tests have been thrown out the window. I can already tell I'm going to have to change most of this later when I'm of a more sound state of mind.

For now, onward.

Tuesday, March 1, 2011

Briefest possible introduction: I'm working on a game project in XNA and I'm using it as a way to experiment with domain-driven design and CQRS with event sourcing. Just go ahead and google any one of those terms and you'll be busy for hours. What follows are some thoughts and notes about a recent change.

After focusing mostly on the event sourcing and XNA parts of the project I recently shifted a bit to focus more on domain-driven design (DDD). I found I was accumulating a lot of junk on what was fast becoming a godlike aggregate root and felt there was a ton of room to clean things up. Things went smoothly for a while but I found my ability to model the domain was limited a bit by the fact that I could only raise events from the aggregate root. That's just how the SimpleCQRS code I started from was implemented. After a little searching it seemed the common solution is to allow the aggregate root's child entities to raise events as well and then merge them into one big stream for the whole root.

I hacked up the SimpleCQRS example a bit to introduce the the entity concept. Here are some rambling thoughts on my implementation that I guess are mainly for me to come back to later:

  • All child entities must set the Guid EntityId property. It currently forces guid but I don't really like that restriction for a few reasons: 1) I prefer entities to have a natural id if possible, 2) The entity id doesn't need to be global, it only needs to be unique within the aggregate root. So a Globally Unique ID might be a bit overkill. Actually I think it will be pretty simply to change this, can probably just make a custom EntityId that initially wraps a Guid and go from there.
  • All events have an EntityId property that is filled out if the event is raised by an entity and left null otherwise.
  • In the constructor of every entity I have to register which events it handles otherwise it will handle none. It bothers me a little so see this registration in every entity's constructor but I guess it's not a huge deal so I'll let it go for now.
  • When an aggregate rebuilds itself from an event history it must route all the events that originated from an entity back to the right entity. This is why both Entity and Event require an EntityId property. The current implementation is kind of dumb though because the event is applied to the aggregate root in addition to the entity. Typing it out makes that sound extra double dumb and I should go remove that soon.
  • I chose to have each child entity delegate to the aggregate root to raise events. This way the aggregate root maintains a single list of changes and since new events are added to the end they are always in the right order. I saw other implementations that involved each entity having its own set of events that are then merged and ordered. This just feels simpler.
Wow, alright. Time for Tosh.