Tuesday, July 22, 2008

Active Record "Mock" Framework



kick it on DotNetKicks.com
Recently, I have been working on my Castle ActiveRecord talk. I am writing some WCF services that will be consumed by a Silverlight client. Because I write my code using TDD, I needed to be able to write tests against the WCF services. I wanted to mock out the backing store for my objects, but with ActiveRecord and NHibernate, this is not so straight-forward. Instead, I came across a post about mocking the backing store for NHibernate tests.

The idea is that you use SQLite in "memory-mode" as your database. This makes it so the database vanishes as soon as your connection is destroyed. This is great for testing! No database server... no database file... pure database interfaces. It is not a mock in the traditional sense of the word, but it lets me write tests as if I had a mock framework.

So, I modified the code to work for ActiveRecord. Note that I am overriding the DriverConnectionProvider to keep the connection alive. This is because the in-memory database gets destroyed when the connection closes.

If you want to use this class, add the following class to your test project. You will need to download and add System.Data.SQLite as a project reference.
namespace ActiveRecordTestHelper
{
public class ActiveRecordMockConnectionProvider : NHibernate.Connection.DriverConnectionProvider
{
private static IDbConnection _connection;

public override IDbConnection GetConnection()
{
if (_connection == null)
_connection = base.GetConnection();

return _connection;
}

public override void CloseConnection(IDbConnection conn)
{
}

/// <summary>
/// Destroys the connection that is kept open in order to keep the in-memory database alive. Destroying
/// the connection will destroy all of the data stored in the mock database. Call this method when the
/// test is complete.
/// </summary>
public static void ExplicitlyDestroyConnection()
{
if (_connection != null)
{
_connection.Close();
_connection = null;
}
}

/// <summary>
/// Initializes ActiveRecord and the Database that ActiveRecord uses to store the data. Call this method
/// before the test executes.
/// </summary>
/// <param name="types">A list of ActiveRecord types that will be created in the database</param>
public static void InitializeActiveRecord(params Type[] types)
{
ActiveRecordStarter.ResetInitializationFlag();
ActiveRecordStarter.Initialize(GetMockConfiguration(), types);
ActiveRecordStarter.CreateSchema();
}

private static IConfigurationSource GetMockConfiguration()
{
var properties = new Hashtable{
{"hibernate.connection.driver_class", "NHibernate.Driver.SQLite20Driver"},
{"hibernate.dialect", "NHibernate.Dialect.SQLiteDialect"},
{"hibernate.connection.provider", ConnectionProviderLocator},
{"hibernate.connection.connection_string", "Data Source=:memory:;Version=3;New=True;"}};

var source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);

return source;
}

private static string ConnectionProviderLocator
{
get { return String.Format("{0}, {1}", TypeOfEnclosingClass.FullName, EnclosingAssemblyName.Split(',')[0]); }
}

private static Type TypeOfEnclosingClass
{
get { return MethodInfo.GetCurrentMethod().DeclaringType; }
}

private static string EnclosingAssemblyName
{
get { return Assembly.GetAssembly(TypeOfEnclosingClass).FullName; }
}
}
}
By using this class, you simply need to initialize ActiveRecord in your test StartUp method, and destroy the connection in the test TearDown Method. Here is an example of a test fixture that takes advantage of my class:
[TestFixture]
public class IngredientServiceTests
{
private IRecipeBoxService _recipeBoxService;

[SetUp]
public void SetUp()
{
ActiveRecordMockConnectionProvider.InitializeActiveRecord(typeof(Ingredient));
_recipeBoxService = new RecipeBoxService();
}

[TearDown]
public void TearDown()
{
ActiveRecordMockConnectionProvider.ExplicitlyDestroyConnection();
}

[Test]
public void Test_Get_Ingredients()
{
Ingredient mockIngredient = new Ingredient("ABCD", "DEF");
mockIngredient.Save();

IList<Ingredient> ingredients = new List<Ingredient>(_recipeBoxService.AllIngredients());

Assert.That(ingredients.Count, Is.EqualTo(1));
Assert.That(ingredients[0].Name, Is.EqualTo("ABCD"));
Assert.That(ingredients[0].Description, Is.EqualTo("DEF"));
}
}

Monday, July 21, 2008

Response to "Self Promotions vs Other Relations"



I had an interesting conversation with someone on Twitter today. He spoke up while I was giving a playful response to someone else. I felt like from there forward, he was misrepresenting me by misquoting me ("everything we do on Twitter", for instance, was a quote I didn't say) and inflating my language by using "everyone", "all the time" and "everything". It ultimately ended up in a blog post of his criticizing my position. I don't know this guy. He might be a troll... he might not... but I felt like I should post my response

I am doing this because I want to make it clear what I think about blogging and being in a community such as Twitter. I believe that there is a spectrum of self promotion, that starts at the core of what Twitter is and ends in the world of fembots.

Here was the Twitter conversation:


sbellware:
the only thing more despicable about self-promotion on twitter is not having the guts to do it in the clear
BrianGenisio @sbellware: Aren't we all, in one way or another, promoting ourselves on Twitter? The act of blogging or micro-blogging is self promotion
vaspersthegrate @briangenisio: - Self promo means pushing links to product pages, blog posts, other sales or self-interest objects. Not altruistic sharing.
vaspersthegrate: Self promotion is not "everything we do on Twitter". There is also selfless interactions and sharing that may not benefit you much at all.
BrianGenisio @vaspersthegrate: Self promotion means a lot more than what you said. Self promotion also means "promoting your ideas". Many others as well
vaspersthegrate @BrianGenisio: - If you think everything everyone does all the time is ultimately selfish, then you can also justify all acts as survival.
BrianGenisio @vaspersthegrate: If you think that you are special enough to "altruistically share", then you are promoting your ego.
vaspersthegrate @BrianGenisio: Helping others on Twitter is not self-promotional, it is other-relational. We know the difference between mktg & helping
BrianGenisio @vaspersthegrate: Just to be clear, I never suggested that you are marketing. I also never used the word "everything". Those are your words

Here is his blog post

Here is my response:
My original statement, which I stand by, was meant to be more of a reflection on our existence on Twitter... I really do understand what the Twitter community means when they say "Self Promotional". I was merely playing with it (the moral relativism of the topic), as my language clearly states.

When we, bloggers, tweeps, professionals and individuals make a blog post or tweet, we are essentially promoting ourselves in one way or another. It may not be in the sense that the Twitter community is referring to, but it certainly is by the meaning of the word. If you look up the word "promote" in the dictionary you will find that what I am saying is true in the first two meanings.

In order to be a member of a community (any community), one must promote themselves in some way... be it through helping others, casual conversation or spouting their opinions. If you do not promote yourself, you are ignored by the emergent community.

Further, a blog is a perfect example of promoting one's ego. I have two blogs -- one personal and a newer, more professional blog. I am not trying to say anything bad about promoting an ego... but instead I am trying to point out that if you are writing something that you think might be useful to others, your ego is being promoted by you -- thus "self promotion".

I urge you to look deeper into what I was saying and not think I am trying to compare you to a fembot on Twitter. I understand the difference.


Friday, July 18, 2008

Comments



Recently, while refactoring an old mess of code, I came across the following:
ArrayList result = new ArrayList(dictionary.Count);

// Loop through the dictionary and add it to the ArrayList
for(int iNdx = 0; iNdx < dictionary.Count; iNdx++)
{
DictionaryItem dictionaryItemValue = dictionary[iNdx];
result.Add(dictionaryItemValue);
}
What is wrong with this code? For me, I see following:
  • ArrayList when we should be using a List<>
  • "for" when we should be using "foreach"
  • A difficult to read loop counter
  • An ugly temporary variable when we should be using none
  • If we used List<>, we would be able to use "AddRange" and bypass the loop entirely.
BUT, none of these are what I find most objectionable. The thing that smells the worst to me is the comment. Yup, that line above the "for" loop. What is it there for? What is its purpose in life? If somebody were to come along and read this code, the comment would only waste their time. It is obvious. Duh.

Comments, by themselves, are a code smell. They muddy the code in a way that makes it harder to read and less maintainable. In fact, I have this poster hanging in my cube at work to remind me in case I am feeling lazy:
To illustrate my point, consider the following inane example: What if I fixed everything about the code that I mentioned preiously:
List<DictionaryItem> result = new List<DictionaryItem>();

// Loop through the dictionary and add it to the ArrayList
result.AddRange(dictionary);
Now I have a comment that doesn't even make sense anymore. You may say "If you made that change, you would change the comment as well." This is false. I am VERY likely to ignore the comment and leave the bad comment in place. Why?
  1. The comment was useless to begin with, so I ignored it.
  2. Most single-line comments are useless, so I ignore it.
  3. The compiler won't tell you that the comment doesn't make sense anymore.
  4. I might be using a tool like ReSharper where most the work is done for me. It ignores comments too.
IT HAPPENS ALL THE TIME.

As far as I am concerned, comments are usually a cheap replacement for readable code. It is easy to slap a comment in and walk away, but it takes thought and effort to make the code readable without the comment.

Now, I am the first to admit... my code readability needs work. More specifically, the way I write code needs work to be readable by others. It is kind of like when I cook (my biggest non-tech hobby). I almost always make food that tastes good... to me. Making it taste as good for others is the thing I am constantly trying to make better.

Here are the categories of comments that I see on a regular basis:

Incorrect Comments
These comments creep int a code base over time as as the code is refactored. If you comment often, then it is inevitable that many of your comments will morph into incorrect comments. These should be eliminated whenever they are found, as they do nothing but confuse the reader. If the code needs a comment, consider refactoring to eliminate the need.

Obvious Comments
So often, a comment is telling you exactly what the code is doing...
// Check For Null
if(item == null)
These comments will quickly become incorrect comments because they are so useless that nobody pays attention to them anyways. They should be removed whenever they are found.

Comments that Replace Readable Code
It takes a lot more effort and creativity to write readable code than it does to comment your code. The problem, again, is that code often changes while comments are often not updated. When this happens, you are left with hard-to-read code with incorrect comments. The author should have encapsulated the code into a concise method that does one thing -- the thing that the comment says that it does.

When you see something like:
List<string> keyData = new List<string>();

// If the file version is old, then parse the old keyed data from the list
if (string.IsNullOrEmpty(v) ||
v.StartsWith("1.") ||
v.StartsWith("2.") && v.EndsWith("b")))
{
foreach (string stuff in ReadStuffFromFile(fh))
{
if (stuff.Contains(_specialKey))
{
string keyItem = stuff.Split(_specialKey.ToCharArray())[1];
keyData.Add(keyItem.Substring(3, 8));
}
}
}
It is so much easier to read if you bust the condition and the block into separate methods:
if (FileVersionIsLegacy(v))
keyData = ParseLegacyData(fh);
Comments that excuse bad code
I am fairly guilty of this one. Comments that say "I know this is bad form, but it is more performant to so it this way" or "Working around a Microsoft bug" are sometimes excusable. Instead, though, a colleague of mine once suggested that I write a method that is named something like HandleListPerformantly() or WorkAroundMicrosoftDisplayBug_3334495() instead. You at least make it obvious to everyone involved what you are doing. Why write a comment when you can use code?

Multi-line comments describing complex behavior
The answer to my last question might be "Because it takes me several lines to describe why I am doing something". I have a hard time arguing with this one. I remember reading in someone's blog recently (I can't remember who, or else I would cite it) Jeff Atwood wrote a post once that code is the "how" and comments are the "why". This is a case where I agree with that statement. I like to stick to the general rule that if a comment is 2 lines or less, I can probably re-write it to be more readable. If it is longer, then my comment is probably useful. Unfortunately, large comment blocks fall victim to accuracy over time even quicker, due to the fact that the nobody who knows the code tends to read those long comments, so they tend to overlook them when they refactor. Consider ways to avoid these blocks as well.

Auto-Documentation comments
I am bringing up this type of comment because every time I have an argument with a staunch comment supporter, they always bring up this case. I will say it now: this doesn't count. It doesn't count because documentation in comments has its own language and stucture. They aren't really comments, but inline documentation meant for external consumers. They get parsed and compiled with a tool, reviewed by a human before delivery and they tend to stay up to date as well as any other documentation method. When I say "Don't write comments in your code", I am not talking about this type of comment.

I may have missed a few prototypes of comments, but for the most part, I think I got them all. I know this is a controversial topic, but the more I argue it, the more I believe I am right on this. The anti-comment sentiment is not new, and it is certainly not unique to me, but I wanted to document my thoughts on it anyway, as it has changed about 179 degrees in the last 3 years. My blog is inteneded to document my thoughts and attitudes about my craft.

Friday, July 11, 2008

Active Record Talk



So at the Ann Arbor .NET Developer's Group meeting the other night, I decided to give a 10 minute "lightning talk" version of my Castle ActiveRecord talk. People seemed very interested in the concept and I will be giving a full-length talk on the topic on September 10th.

Unfortunately, my company considers my first demo and presentation to be their IP and I can't use it for a public talk. Because of this, I need to come up with a new demo and a new PowerPoint stack. I suppose this is not the worst thing in the world, as it will force me to think about the holes and questions from my internal talk.

My wife and I give each other alternating Fridays to get out of the house and do "our thing" while the other stays home while our child sleeps. So, I am at the coffee shop tonight, listening to music and playing more with ActiveRecord. I am thinking of a full-blown Silverlight application for recipe management as my demo.

Thursday, July 10, 2008

PDC 2008




I just signed up for PDC this year and reserved my airline ticket. I am excited to go to this, as it will be the highest profile development conference I have ever attended... by far. It will suck being away from my wife and 18 month old daughter for that long, but I think this conference will be a good thing for me.

Before I started my .NET job 2.5 years ago, I only had 1 year of Windows development experience. Before that, it was all cross-platform, unix-like environments. Windows is still relatively new to me as a platform. Because of this, I certainly have never been to anything so M$ focused. I am going with a colleague from my office, so it should be a good time. If you are going, I will see you there!

Tuesday, July 8, 2008

Castle Active Record


I have recently gotten into databases at work. I HATE programming against databases. I have spent the majority of my career avoiding jobs where I need to program against them. I just don't like doing it. I mean, they are great for persistence and retrieval, but I hate how muddy they make the code... all the CRUD (Create, Retrieve, Update and Delete) code that needs to be written... all the special queries... yuck.

Which is why in my current project (a re-architecture of an existing system) when it came time to include a database instead in place of the dreaded XML files, I found myself in a tough spot. I really like the active record pattern, so I implemented my business object persistence using that pattern.

While doing this, I came across an amazing open-source product called Castle ActiveRecord (part of the Castle Project). Coincidentally, I got to see a talk by Michael Eaton at Lansing Day of .NET a few weeks later. It is a simple framework that abstracts away all database programming. WOW! What could be better? It is amazingly simple to use and I barely touch the database. I don't even need to create the database schema. Castle ActiveRecord does it all for me.

So I did what I often do when I want to learn a new technology... I signed up for a tech talk to my developer team on the topic. I gave an hour-long talk on the Active Record pattern and the Castle ActiveRecord framework. With it, I came up with a fully functional (albeit toy-like) demo project.

The project is a Recipe Box application. My business objects and database schema look like this:

They are freakishly similar. The beauty is that I never had to write the schema. ActiveRecord did it for me.

Here is the guts of my business object code:
[ActiveRecord]
public class Recipe : ActiveRecordBase<Recipe>
{
[PrimaryKey]
public int Id { get; set; }

[Property]
public string Title { get; set;}

[Property]
public string Description { get; set; }

[Property]
public string Author { get; set; }

[HasMany(Inverse = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
public IList<Step> Steps { get; set; }

[HasMany(Inverse = true, Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
public IList<Quantity> Quantities { get; set; }
}

[ActiveRecord]
public class Step : ActiveRecordBase<Step>
{
[PrimaryKey]
public int Id { get; set; }

[Property]
public string Command { get; set; }

[BelongsTo("RecipeId")]
public Recipe Recipe { get; set; }
}

[ActiveRecord]
public class Quantity : ActiveRecordBase<Quantity>
{
[PrimaryKey]
public int Id { get; set; }

[Property]
public double Value { get; set; }

[Property]
public Units Units { get; set; }

[BelongsTo("IngredientId")]
public Ingredient Ingredient { get; set; }

[BelongsTo("RecipeId")]
public Recipe Recipe { get; set; }
}

[ActiveRecord]
public class Ingredient : ActiveRecordBase<Ingredient>
{
[PrimaryKey]
int Id { get; set; }

[Property]
public string Name { get; set; }

[Property]
public string Description { get; set; }
}

It is that simple (I left out constructors, ToString() and other logic for this post. I load it up and start programming against the objects:

Create:

var ingredient = new Ingredient("Milk", "A drink made from mammals");
ingredient.Save();
Retrieve:

Ingredient.FindAll();
Update:

ingredient.Description = "A white liquid";
ingredient.Save();
Delete:

ingredient.Delete();
It couldn't be any easier, as far as I am concerned. Delete, Save, FindAll and many other methods like those were created for me when I inherited my objects from ActiveRecordBase. This gives me a ton more time to be coding my features, and forgetting about my persistence mechanism.

As much praise as I have given to ActiveRecord, there are some weaknesses. Here are the ones I can point out:
  • You have less control over your database
  • It is not as performant as direct SQL and stored procedures can be
  • You loose your one shot at inheritance. If your business objects already derive from something, you are out of luck
  • It cause an even bigger rift between Devs and DBAs
  • You are forced to write classes with strong dependencies with each other
  • You need to deploy at least 6 Dlls at 1.6 MB in size

Finally, I want to make a quick mention to Microsoft's Entity Framework. It is supposed to do a lot of what Casltle ActiveRecord already does. It is currently in CTP, and I will probably play with it soon. Unfortunately, many in the development community have given it a vote of "No Confidence". I am not qualified to judge here, but I hope that when EF comes out later this year, the community is a bit more positive about it. We'll see.