Tuesday, January 31, 2006

.norm insert usage

The DataGateway class is the facade to the .norm framework. Insert, Update, Delete, and Find are all completed by using the DataGateway class. The DataGateway class has only one requirement, an instance of type IConnectionInfo. The ConnectionInfo class is a simple data object that contains the data source, catalog, user, and password of the database you are attempting to use. All of the data elements of the ConnectionInfo class are required constructor arguments.

Using DataGateway to insert data can be accomplished by doing exactly what you would expect.
Foo user = new Foo();
user.FirstName = "Jay";
user.lastName = "Fields";
user.ID = 0;

ConnectionInfo info = new ConnectionInfo("data_source","my_catalog","user_name","password");
DataGateway gateway = new DataGateway(info);
gateway.Insert(user);
In this example you are inserting an instance of type Foo into the database. Foo is designed as follows.
namespace Example
{
public class Foo
{
public int ID;
private string firstName;
private string lastName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
}
.norm uses reflection to persist the instance of the Foo class to a table named Example.Foo. By default .norm uses a type's FullName as the table name to persist an instance to. .norm also assumes that the columns of the Example.Foo table have the names ID, FirstName, and LastName. Again, reflection is used to map the values of public fields and properties to columns of the same name.

Additionally, if you need to customize the table and column names .norm uses attributes for object mapping.

Assume you want to put the same Foo object into a table named foo_user_data. Also, assume the columns in foo_user_data are f_name, l_name, and id. The insert code will remain exactly the same, but the definition of the Foo class will need to include attributes that specify the mapping names.
namespace Example
{
[RelationalMapped("foo_user_data")]
public class Foo
{
[Column("id")]
public int ID;
private string firstName;
private string lastName;

[Column("f_name")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

[Column("l_name")]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
}
After making these additions to the Foo class it will be persisted to foo_user_data table when Insert is executed. Note, despite the fact that the ID column did not need a different name specified, you must explicitly specify each member that needs to be persisted on a class decorated with the RelationalMapped attribute.

Monday, January 30, 2006

.norm version 0.1 released

.norm is a new .net object relational mapper.

.norm was designed with the following features in mind:
  • No additional code, such as default constructors, are necessary.
  • Object CRUD operations should be possible without any database mapping necessary.
  • Objects with dependencies should be in a valid state when they are returned from the database.
  • A single class will map to a single table in the database.
  • Database mapping will be done via reflection by default and attributes when specific names are necessary.
  • Mapping via attributes instead of XML.

No additional code. A default constructor is not necessary because .norm depends on a PicoContainer for object creation. If your class does not contain a default constructor you can register the dependencies with the DataGateway and it will use PicoContainer to construct your object using the greediest constructor it can satisfy.

CRUD for free.The .norm framework uses reflection for persisting to and retrieving objects from the database. By default the FullName of a type is used as a table name, and each public field name and public property name are used as columns of the table. Additionally, .norm provides a RelationalMappedAttribute that can be used to specify a table name. And, A ColumnAttribute can be used to specify a column name. By default all public fields and properties are persisted; however, if a class is decorated with a RelationalMappedAttribute, only the attribute decorated public fields and properties will be persisted.

Dependencies are injected before objects are returned. By default, DataGateway creates a PicoContainer instance at construction time. DataGateway exposes PicoContainer's registration methods allowing you to register dependencies without ever dealing with PicoContainer, if you desire. DataGateway also takes a PicoContainer as a constructor argument if you already have an initialized PicoConstructor.

.norm is simple. All insert, update, delete, and find actions can be completed through the DataGateway class. When you need specific data returned, the WhereBuilder class allows you to narrow your results. Those should be the only classes necessary to begin using .norm.

.norm can be downloaded here.

More information to follow in the next few days.

Thursday, January 26, 2006

Use stubs and mocks to convey intent

I've previously stated that only one concrete class should be used per test. I stand by this statement; however, this leads to the question "What should I use for the dependencies of the concrete class under test?"

To illustrate I will use a SqlStatementBuilder class that depends on an instance of IPersistable and an instance of IWhereBuilder. SqlStatementBuilder takes an IPersistable instance which is an object that exposes a name. SqlStatementBuilder uses IWhereBuilder to append a where clause.
class SqlStatementBuilder...
public SqlStatementBuilder(IPersistable instance, IWhereBuilder where)
{
this.instance = instance;
this.where = where;
}

public string CreateFindAllStatement()
{
string mask = "select * from {0} {1}";
return string.Format(mask,instance.Name,where.ToString());
}
Testing SqlStatementBuilder requires you to create instances of both IPersistable and IWhereBuilder. However, if concrete implementations are used any changes to Persistable or WhereBuilder would cascade and could potentially break SqlStatementBuilder tests.

After deciding to use stubs or mocks the decision becomes which of these two options is the best. Some feel that choosing mock or stub usage is exclusive; however, using both is the superior option. A mixture of both solutions can be used to clearly convey the intended usage of a dependency within the current test.

Using a mock to verify the class under test interacts in an expected manner with a dependency is natural. However, tests should verify behavior of a dependency independently of other dependencies. For all dependencies who's behavior is not currently under test a stub is preferred. By using stubs in this manner you convey the message that only the interaction of the class under test and the mocked dependency is important.

For example, if I were testing the CreateFindAllStatement method I would test both that IPersistable.Name was used as the table name and that IWhereBuilder.ToString() was appended to the end of the select statement.
[TestFixture]
class SqlStatementBuilderTests...
[Test]
public void IPersistableNameIsUsedAsTheTableNameInCreateFindAllStatement()
{
IMock mock = new DynamicMock(typeof(IPersistable));
mock.ExpectAndReturn("Name","Foo");
IPersistable persistable = (IPersistable)mock.MockInstance;

SqlStatementBuilder builder = new SqlStatementBuilder(persistable,new StubWhereBuilder());
Assert.AreEqual("select * from Foo ",builder.CreateFindAllStatement());
mock.Verify();
}

[Test]
public void WhereBuilderToStringIsAppendedToTheEndOfAFindAllStatement()
{
IMock mock = new DynamicMock(typeof(IWhereBuilder));
mock.ExpectAndReturn("ToString","where...");
IWhereBuilder where = (IWhereBuilder)mock.MockInstance;

SqlStatementBuilder builder = new SqlStatementBuilder(new StubPersistable(),where);
Assert.AreEqual("select * from where...",builder.CreateFindAllStatement());
mock.Verify();
}
Developing tests in this manner will increase the readability due to the conciseness and clear intent. Additionally, changing the interaction between a class under test and a dependency will only break the tests specific to that dependency. The tests become more durable because a stub's default behavior should be to return a default value or do nothing in the case of a void method. Therefore, stubs will not need to be updated based on a behavioral change.

Tuesday, January 24, 2006

Use delegates to replace repeated guard clauses

When working with Presentation Model a recurring source of pain is the isLoading guard clause. The isLoading guard is required on the Reload method. Despite not being required, I also prefer to have my setting methods guarded. If you choose not to guard setting methods the last changed value will be set in the Presentation Model twice (once where you set it and once when Reload raises the XChanged event).

For example:
class FooView...
FooView(FooPM pm)
{
this.pm=pm;
Reload();
}
...
private TextBox barTextBox;
private FooPM pm;
private bool isLoading=false;
...
public void Reload()
{
if (!isLoading)
{
isLoading=true;
barTextBox.Text=pm.BarText;
isLoading=false;
}
}

public void barTextBox_TextChanged(object sender, EventArgs e)
{
if (!isLoading)
{
pm.BarText=barTextBox.Text;
Reload();
}
}
}
As the number of data elements on the screen increases so does the annoyance with repeating the isLoading guard.

You can solve this issue by extracting the setting code into it's own method, creating a delegate to this method, and passing the delegate to the Reload method. The reload method can first set the value of isLoading and then execute the delegate.
class FooView...
...
public void Reload(SetDelegate setMethod)
{
if (!isLoading)
{
isLoading=true;
setMethod();
barTextBox.Text=pm.BarText;
isLoading=false;
}
}

public void SetBarText()
{
pm.BarText=barTextBox.Text;
}

public void barTextBox_TextChanged(object sender, EventArgs e)
{
Reload(new SetDelegate(SetBarText));
}
}
The resulting code is one method longer, but removes the isLoading repetition.

I prefer Rake to NAnt (#4)

I prefer Yaml for Ruby to the Configuration classes in the .net framework.
Configuration information is often stored in a text file. When using Rake the information can be put into a yaml file that is highly readable and maintainable without all the unnecessary noise.
--- !ruby/object:Configuration 
catalog: cat
data_source: source
password: password
user: jay
Next, you will need to create a Configuration class. Yaml.rb::load will automatically load your configuration information into an instance of the Configuration class.
class Configuration
attr_accessor :user, :password, :data_source, :catalog
end
At this point you are ready to access your configuration information via methods of the object. The following test verifies the expected behavior.
require 'yaml'
require 'test/unit'

class TestConfiguration < Test::Unit::TestCase
def testYmlLoaded
config = YAML::load(File.open('config.yaml'))
assert_equal("jay",config.user)
assert_equal("password",config.password)
assert_equal("source",config.data_source)
assert_equal("cat",config.catalog)
end
end
*SciTE formatting

Monday, January 23, 2006

Rake NUnit Task

The adoption rate of rake is strongly slowed by the lack of prebuilt tasks. Despite NAnt's flaws, it is attractive to those who need only simple tasks such as compile (solution task) or unit test (nunit task).

I have word from a good source that Jim Weirich is working on a plug-in architecture for Rake that will allow for easy rake task creatioin. With more tasks available the adoption rate will increase.

This is great news; however, you don't have to wait for this architecture to create your own rake tasks. On my current project I wanted to make the rakefile more readable for the developers who were less familiar with rake. One way to accomplish this is to abstract a few variables and a shell execute into a task.

I chose to use NUnit as the example; however, the idea can be applied to any task that is completed by a commandline application (Simian, Devenv.com, etc). The NUnit task requires only the Library value; however, it does allow you to specify optional xml and config information. Adding other commandline switches could be accomplished very easily by following the same model. To use this task all you need to do is save the code to nunittask.rb in the lib folder.
#!/usr/bin/env ruby

require 'rake'
require 'rake/tasklib'

module Rake

class NUnitTask < TaskLib
# Name of the main, top level task. (default is :nunit)
attr_accessor :name, :library, :xml, :path_to_console, :config

# Create an NUnit task named nunit. Default task name is +nunit+.
def initialize(name=:nunit) # :yield: self
@name = name
@path_to_console = "lib/nunit-console.exe"
yield self if block_given?
define
end

# Create the tasks defined by this task lib.
def define
task name do
sh "#{@path_to_console} #{xml} #{config} #{library}"
end
self
end

def xml
"/xml=#{@xml}" if @xml
end

def config
"/config=#{@config}" if @config
end
end
end
Now that you have NUnitTask saved it can be used in your rakefile simply by adding an NUnitTask.
require 'lib/nunittask'
...
Rake::NUnit.new do |nunit|
nunit.library = "foo.dll"
end
You can wrap any commandline task in the exact same way. If you create enough of them, your rakefile reads much more like a specification than a ruby program.

Thursday, January 19, 2006

I prefer Rake to NAnt (#3)

I prefer Ruby's multi-threading to NAnt's lack of.
The current application I'm working on has lots of data. With every build we drop, create, and reload the objects in the database. The drop and create sql must be executed first, but the loading scripts can be run in parallel. Ruby makes this easy with the Thread class in the Core API.
task "setup_db" do
tasker = DbTasks.new
tasker.execute_osql("object_drop_and_creation.sql")

#execute in parallel
threads = []
threads << Thread.new { tasker.execute_osql("dummy_data1.sql") }
threads << Thread.new { tasker.execute_osql("dummy_data2.sql") }
threads << Thread.new { tasker.execute_osql("dummy_data3.sql") }
threads << Thread.new { tasker.execute_osql("dummy_data4.sql") }
threads << Thread.new { tasker.execute_osql("dummy_data5.sql") }

#join threads
while ( t = threads.shift ) ; t.join ; end
end
*DbTasks is simple class that contains common information (login info). The DbTasks.execute_osql method is just a wrapper for executing osql as a system command with DbTasks' static information.

**As usual, there may be a better way in Ruby. And, there may be multi-threading options in NAnt that I'm not aware of.

Tuesday, January 17, 2006

Moving from NAnt to Rake

Build scripts often contain both trivial and non-trivial tasks. Many of the non-trivial tasks can be completed easily by creating a ruby script to perform the complex logic. The new ruby script can be executed via a NAnt exec task.

If you are working with an existing NAnt script that is a burden to maintain consider converting the more complicated tasks into ruby scripts. When the majority of the complicated tasks are written in ruby it will make sense move the remaining tasks into a rakefile.

I used this approach recently at a client site. Whenever the NAnt tasks needed updating we converted them to a ruby script. When we finally decided to make the move to rake exclusively it took less than an hour to convert the remaining tasks. The resulting rakefile was about 1/2 as long. Additionally, the team agreed that the resulting rakefile was significantly more readable and maintainable.

Friday, January 13, 2006

Fragile Development

There might be a problem when...

instead of refactoring duplicate code you just ignore it.
#region simianignore - logic same among all screens

you hear:
"I don't like to check in often, the tests take too long to run"

Friday, January 06, 2006

I prefer Rake to NAnt (#2)

I prefer Ruby's libraries to NAnt's tasks.
Recently, I was asked to add a step to the build file that would delete all build outputs that were older than 2 weeks old. The build output is stored in a folder in the distrobution folder. I'm not even going to attempt this task in NAnt, but using Ruby's find, delete, and fileutils the code was quite easy to write. (I admit, this could probably be done even better, but this was the first thing that came to mind.)
require 'find'
require 'date'
require 'fileutils'

root_dir = "C:/Dist"
two_weeks_ago = Date.today - 14

puts "deleting files last modified before #{two_weeks_ago}"
Find.find(root_dir) do |path|
if File.dirname(path) == root_dir
file_modify_date = Date.parse(File.mtime(path).strftime("%m/%d/%Y"))
puts "#{path} last modified on #{file_modify_date}"
if file_modify_date < two_weeks_ago
puts "#{path} removed"
FileUtils.rm_rf(path)
end
end
end

I prefer Rake to NAnt (#1)

While working with Rake and NAnt I've found several reasons I prefer Rake. And, I've received several requests for a pro/con list concerning Rake. So, I'm going to start keeping a list. Here's reason #1.
I prefer escape characters (\") and Q delimiters (%Q) to entity codes (&quot;).
For example, executing an external program where the 1st parameter needs to be in quotes but not the second.
Rake (option 1): exec "foo.exe \"some text\" bar"
Rake (option 2)*: exec %Q[foo.exe "some text" bar]
NAnt: <exec program="foo.exe" commandline="&quot;some text&quot; bar"/>
*option 2 provided by Martin

NAnt exec: add quotes to commandline

After posting NAnt exec: arg || commandline, an anonymous reader asked how to add quotes to some arguments and not others.

A simple solution would be to use commandline and delimit the string with single quotes.
<exec program="ruby" commandline='parse_text.rb "some text file.txt"'/>
However, this solution feels like a hack and isn't immediately obvious.

Another (even less obvious) solution is to use &quot;.
<exec program="ruby" commandline="parse_text.rb &quot;some text file.txt&quot;"/>
This doesn't read very well, but it feels less like a hack because you can use a standard double quote delimiter.

Either option you choose isn't very pleasing. Which leads me to reason #1 why I prefer Rake to NAnt.

Trust Visibility

Long before I joined ThoughtWorks I wrote a Data Access framework with a very simple public interface. The entry point to the framework was a IDataManager interface that contained Save(..), Delete(..), and Find(..). The framework was composed of several collaborating classes, but only the IDataManager interface was public. I designed the code this way because of fear. I was afraid that if I gave developers the rope, they would hang themselves.

During the development of this framework I came up with the idea of Accessing Private Members using conditional compilation. While interviewing with ThoughtWorks I briefly discussed this situation with Greg Warren. He suggested (but did not take credit for the idea) using a correctly scoped interface and making the methods of the concrete classes public. At the time, this sounded like a large risk. I didn't trust the other team members enough to give them that option.

Since joining ThoughtWorks, my opinion has completely changed. I now subscribe to the idea that a language should only have public and protected access (which I first heard from Zak Tamsen). So many language constructs are designed to protect us from ourselves that we often tie our own hands together. I'd prefer to have the rope and see what I can do with it. However, I strongly believe that I changed my mind based on the fact that I now trust the team I am working with. Because of this trust I don't feel I need to tie their hands together. And, with untied hands, my teammates produce some pretty brilliant ideas.

To me, this proves once again that People Matter Most.