Sunday, March 29, 2009

Experimenting With Fluent Interfaces in the Domain

As you might have guessed from my previous two blog posts, I've been experimenting with fluent interfaces lately. I've been thinking about passing an expression builder to an aggregate root so that the root entity can use the builder to create a particular child entity. This begs for some code.

Suppose I have an aggregate root called Category. A Category can have a list of Items. So in order to add another Item to a Category, the code might look like this.

public class Category : DomainEntity
{
    private readonly ISet<Item> _items;
    public virtual String Name { get; private set; }
 
    protected Category()
    {
        _items = new HashedSet<CatalogItem>();
    }
 
    public void Categorize(String productNumber, 
                     String itemName, String manufacturer)
    {
        var item = new Item(productNumber, itemName, 
                            manufacturer);
        _items.Add(item);
    }
}

The Categorize method adds a new Item to the Category. What I don't like about this method is the number of arguments, even for this simple example. In real life, there can be plenty of arguments that need to be passed to this method. Another thing that somewhat disturbs me is the fact that the Category class is also responsible for creating an Item class.

Lets see what I ended up with using an expression builder. First I created one for building an Item.

public interface IItemBuilder
{
    Item Build();
}

 

public class ItemBuilder 
    : DomainObjectBuilder<Item>,
      IItemBuilder
{
    protected Manufacturer Manufacturer { get; set; }
    protected String Name { get; set; }
    protected Product Product { get; set; }
 
    public ItemBuilder Named(String name)
    {
        Name = name;
        return this;
    }
 
    public CatalogItemBuilder ManufacturedBy(
                   Action<ManufacturerBuilder> buildUsing)
    {
    var manufacturerBuilder = new ManufacturerBuilder();
        buildUsing(manufacturerBuilder);
 
        Manufacturer = manufacturerBuilder.Build();
        return this;
    }
 
    public CatalogItemBuilder ForProduct(
                        Action<ProductBuilder> buildUsing)
    {
        var productBuilder = new ProductBuilder();
        buildUsing(productBuilder);
 
        Product = productBuilder.Build();
        return this;
    }
 
 
    public override Item Build()
    {
        return new Item(Name, Manufacturer, Product);
    }
}

This is a quite straightforward expression builder where the creation of Manufacturer and Product value objects is handed of to other expression builders, which are not important for this example. Notice the IItemBuilder interface, which can now be used by the Categorize method.

public void Categorize(IItemBuilder itemBuilder)
{
    var item = itemBuilder.Build();
    _items.Add(item);
}

This way I both eliminate the number of arguments I need to pass to the method and the code creating an Item object, which is now moved to the expression builder. Notice that by passing in an instance of IItemBuilder, the domain object is unaware of the actual expression builders themselves which live on top of the domain entities and value objects anyway. Now, in order to remove the need of creating an instance of an ItemBuilder in the layers that use the domain, I added an extra extension method that does that for us.

public static class CatalogCategoryExtensions
{
    public static void Categorize(
        this CatalogCategory catalogCategory, 
        Action<CatalogItemBuilder> buildUsing)
    {
        var catalogItemBuilder = new CatalogItemBuilder();
        buildUsing(catalogItemBuilder);
        catalogCategory.CategorizeItem(catalogItemBuilder);    
    }
}

This results in the following syntax in the application service (except for the hard-coded values, of course).

category.Categorize(item =>
    item.Named("iPhone")
    .ManufacturedBy(manufacturer => 
        manufacturer.Named("Apple")) 
    .ForProduct(product =>
        product.Numbered("AA1687")));

Although this all looks good, I'm not entirely sure of this approach yet but it certainly looks interesting to me. All feedback is more than welcome, off course. I could be totally jumping the shark on this one :-). So let me know what you think.

Saturday, March 28, 2009

Book Review: The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich

51FSaZaVA3L._SL500_AA240_Yesterday, I finished listening to the 4-Hour Workweek and I really liked it. That's right, I said 'listening' because I have the audio version of the book.

While the title does make a bold statement, as a reader (or listener) you have to look through the facade of making lots of money while spending all of your time doing the things you'd like to do. Once you see beyond that facade, a lot of useful advice emerges. I'm sure that almost everything that Tim Ferriss describes in his book worked out great for him. On the other hand, the things he achieved in his life didn't came without consideration and preparation as opposed to some of the bold statements he made in the book.

Nonetheless, this book is filled with good advice on how to take your life into our hands. In fact, I've been applying some of the things he described and I like where things are going. I'm not drastically changing my life yet, but this book certainly got me thinking about some stuff.

Anyway, the book is divided into four sections, each describing a particular aspect of lifestyle design.

D is for Definition

This part discusses why setting your goals is important. The general advice is to avoid working yourself to death, looking forward to your retirement that may as well never come. Asking yourself "What do I really want?".

E is for Elimination

This particular part really struck a chord. This part of the book talks about how to get yourself on an information diet. I've started implementing this diet as soon as I finished this chapter. Now, I only read email three times a day, I started eliminating all multitasking immediately, I'm slowly declining meeting requests where I can't be of any use, don't have a clear agenda or that has nothing to do with my current activities. I'm even thinking about hanging up a "do not disturb" sign ;-). I've been doing this for two weeks now, and I can notice some clear improvements.

A is for Automation

If I had to choose the least interesting part of the book, then this would be it. Here the author talks about outsourcing your life (which maybe interesting when it comes to maintaining the garden). Besides that, he also provides a lengthy description of how to become a successful entrepreneur. 

L is for Liberation

This final part  puts all the pieces together from the previous parts. Very good advice about working remotely and how to achieve more efficiency this way. All in all, very inspirational stuff.

I enjoyed listening to this book so much that I also just ordered a hard copy. Why would I still want the book itself despite having the audio version? Whenever I read a book, I tend to stop reading for some time every time I want to give some thought about the particular topic I've read. This is rather difficult with the audio version, especially while being in traffic :-). Second, this book contains a lot of links to some interesting web sites. It would come rather in handy as a reference later on and for reading it a second time.

I can certainly recommend that you read this book. Maybe it will change your life.  What do you have to loose?

About Working With a Shared Database

I just wanted to share this quote that I've read while I was skimming through Enterprise Integration Patterns. This paragraph clearly phrases my thoughts about a Shared Database, also because I've been confronted with its downsides for quite some time now.

One of the biggest difficulties with Shared Database is coming up with a suitable design for the shared database. Coming up with a unified schema that can meet the needs of multiple applications is a very difficult exercise, often resulting in a schema that application programmers find difficult to work with. And if the technical difficulties of designing a unified schema aren't enough, there are also severe political difficulties. If a critical application is likely to suffer delays in order to work with a unified schema, then often there is irresistible pressure to separate. Human conflicts between departments often exacerbate this problem.

This sounds so familiar to me that it isn't even funny anymore.

To makes things clear, I personally believe that implementing a shared data model for multiple applications is a very bad idea. The same goes for trying to  achieve the one and only domain model. The blue book has a solution for that, called the BoundedContext. The solution for a Shared Database is a private data model that should never be shared to the outside world.

So if you have a choice, do the right thing.

Sunday, March 22, 2009

One Scenario Where the System.DirectoryServices. AccountManagement API Falls Down

About a year ago, I wrote a post about Directory Programming with System.DirectoryServices. AccountManagement. I've been using the AccountManagement API of the .NET 3.5 framework since then and I still like its simplicity over the raw API of the System.DirectoryServices namespace.

Over the past year, however, I've encountered one scenario where I was forced to go back to using the dreadful DirectoryEntry class. This scenario involved managing Active Directory groups for a user. Basic stuff you might say. Now, I want to add that everything works fine if your code is running on a machine that lives within the same domain as the domain controller, which is most of the cases.

However, when the server machine lives in another domain than the domain controller that accommodates the Active Directory you need to manage, then you've just stepped into a whole different ball game.

Still, you can be saved when a trust exists between these two domains. If not, then you're out of luck (and so was I). In this particular scenario, whenever you want to add or remove a user from a group, then the following error is raised:

Information about the domain could not be retrieved (1355).

When you see this error message appearing on your screen, you have two options:

  1. Investigate whether a trust can be set up between the domain of your server and the other domain where the Active Directory server lives.
  2. If for security reasons a trust is not an option, then go back and use the old DirectoryServices API's. They will handle this scenario perfectly, although the readability of your code will suffer.

I can only hope that this gets fixed in the next release of the .NET framework.

Progressive Interfaces

David wrote this post about a month ago where he challenged the usefulness of fluent interfaces. One of his concerns is the discoverability of a fluent API in order to determine what the correct syntax should be. Whenever you're new to a particular fluent API, it may not always be obvious what the API developer had in mind when he designed it. This can be a pain point and certainly when you don't have any examples of how the fluent API syntax should look like.

This can be improved, however, by using progressive interfaces. This is certainly nothing new and is already being used by popular fluent API's like the one provided by StructureMap.

Let's start by showing a 'traditional' expression builder like the one I provided in my previous post:

public class ProductBuilder
{
    private String Manufacturer { get; set; }
    private String Name { get; set; }
    private Double Price { get; set; }
 
    public static ProductBuilder CreateProduct()
    {
        return new ProductBuilder();
    }
 
    public ProductBuilder Named(String name)
    {
        Name = name;
        return this;
    }
 
    public ProductBuilder ManufacturedBy(
        String manufacturer)
    {
        Manufacturer = manufacturer;
        return this;
    }
 
    public ProductBuilder Priced(Double price)
    {
        Price = price;
        return this;
    }
 
    public static implicit operator Product(
        ProductBuilder builder)
    {
        return builder.Build();
    }
 
    private Product Build()
    {
        return new Product(Name, Manufacturer, Price);
    }
}

Notice that I've implemented method chaining by letting the ProductBuilder return an instance of itself. Whenever I'm using Intellisense for discovering the API of an object, I get to see all the methods provided by the expression builder.

Intellisense01

For this simple example it isn't really a problem. But imagine for a moment that we as the designers of this fluent API want our users to first provide the name, then the manufacturer and last but not least the price of a Product. In order to automatically fall into the pit of success, we can use progressive interfaces to clearly communicate our intent. First we need to create/extract the necessary interfaces that we will be using as a return type for every consecutive method call of our expression builder.

public interface IPreProductNameBuilder
{
    IPostProductNameBuilder Named(String name);    
}
 
public interface IPostProductNameBuilder
{
    IPostProductManufacturerBuilder ManufacturedBy(
        String manufacturer);
}
 
public interface IPostProductManufacturerBuilder
{
    Product Priced(Double price);    
}

Next step is to adjust the methods of the expression builder so that they no longer returns its the type of the expression builder itself but one of these progressive interfaces instead. Notice that the ProductBuilder class also implements every interface we just defined. This way the ProductBuilder can keep returning the instance of itself. Below is the modified code of the ProductBuilder that now uses the progressive interfaces we just defined.

public class ProductBuilder : IPreProductNameBuilder,
                              IPostProductNameBuilder,
                              IPostProductManufacturerBuilder
{
    private String Manufacturer { get; set; }
    private String Name { get; set; }
    private Double Price { get; set; }
 
    public static IPreProductNameBuilder CreateProduct()
    {
        return new ProductBuilder();
    }
 
    public IPostProductNameBuilder Named(String name)
    {
        Name = name;
        return this;
    }
 
    public IPostProductManufacturerBuilder ManufacturedBy(
        String manufacturer)
    {
        Manufacturer = manufacturer;
        return this;
    }
 
    public Product Priced(Double price)
    {
        Price = price;
        return this;
    }
 
    public static implicit operator Product(
        ProductBuilder builder)
    {
        return builder.Build();
    }
 
    private Product Build()
    {
        return new Product(Name, Manufacturer, Price);
    }
}

Now the intended syntax for the fluent API can easily be discovered by just using Intellisense.

Intellisense02

 

 

Intellisens03

 

 

Intellisens04

 

 

 

Using progressive interfaces may be slightly more work (but as always, Reshaper is your friend). The gain however is making your fluent interfaces much easier to discover by expressing your intent to the poor guy that needs to consume them..

Saturday, March 21, 2009

Be Careful With the var Keyword and Expression Builders

I just want to point out a small tidbit I ran into earlier this week. I was using the following simplified expression builder that provides a fluent interface for creating an instance of a Product.

public class Product
{
    public Double Price { get; private set; }
    public String Name { get; private set; }
    public String Manufacturer { get; private set; }
 
    public Product(String name, String manufacturer, 
                   Double price)
    {
        Price = price;
        Name = name;
        Manufacturer = manufacturer;
    }
}
 
public class ProductBuilder
{
    private String Manufacturer { get; set; }
    private String Name { get; set; }
    private Double Price { get; set; }
 
    public static ProductBuilder CreateProduct()
    {
        return new ProductBuilder();
    }
 
    public ProductBuilder Named(String name)
    {
        Name = name;
        return this;
    }
 
    public ProductBuilder ManufacturedBy(
        String manufacturer)
    {
        Manufacturer = manufacturer;
        return this;
    }
 
    public ProductBuilder Priced(Double price)
    {
       Price = price;
        return this;
    }
 
    public static implicit operator Product(
        ProductBuilder builder)
    {
        return builder.Build();
    }
 
    private Product Build()
    {
        return new Product(Name, Manufacturer, Price);
    }
}

The following code is an example of how to use this expression builder.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);

There is one minor inconvenience with this code. One may think that the product variable contains an instance of a Product. Unfortunately, this is not the case. The product variable however contains an instance of ProductBuilder and not an instance of Product because the implicit cast operator is never called. How would the compiler know that you want to keep a reference to Product and not a ProductBuilder? Bringing in a bit more ceremony makes this code more easier to comprehend without side effects.

Product product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);

A small price to pay for better readability. On the other hand, you will never encounter this when you pass in the Product to another method.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch")
    .ManufacturedBy("Apple")
    .Priced(273);
 
DoSomethingWith(product);
 
 
 
public void DoSomethingWith(Product product)
{
    // ...
}

In this case the implicit cast operator does get called when passing the ProductBuilder instance to the DoSomethingWith method. If lazy initialization is what you want, then the var keyword is the perfect match for this.

var product = ProductBuilder
    .CreateProduct()
    .Named("iPod Touch");
 
// Do something else
 
product.ManufacturedBy("Apple")
    .Priced(273);

This may all be straightforward stuff, but I noticed that it kept bugging me every time I didn't paid attention.

Sunday, March 08, 2009

What I Really, Really, Really Like About Using Fluent NHibernate

Reusable Mappings

Something that slightly bothered me with the XML mappings of NHibernate, is the fact that some things need to be configured over and over again. Behold the following two mapping files:

Catalog:

  <class name="Catalog" table="`Catalog`" optimistic-lock="version">

    <id name="Id" column="Id" type="Guid">

      <generator class="guid.comb" />

    </id>

    <version column="Version" name="Version" />

    <property name="Name" length="100" type="String">

      <column name="Name" />

    </property>

    ...

  </class>

CatalogCategory:

  <class name="CatalogCategory" table="`CatalogCategory`" optimistic-lock="version">

    <id name="Id" column="Id" type="Guid">

      <generator class="guid.comb" />

    </id>

    <version column="Version" name="Version" />

    <property name="Description" length="100" type="String">

      <column name="Description" />

    </property>

    ...

  </class>

Suppose we have the luxury to choose how we deal with the database in our project. I do realize that's not always feasible because at some point in our careers, we've all seen what database masochism can do. Anyway, if would be making the shots, I would like to use a surrogate key for every table and I would recommend sequential GUIDs (called COMBs) for that. 

The mapping of the classes shown above both have the same configuration for the Id and Version properties. These properties typically live in a DomainEntity base class of some sort because we don't want to repeat that tedious code of putting those in every entity of our domain over and over again. It would be nice if we could somehow do the same for the NHibernate mapping files, which we can't (or at least, not that I know of).

Using Fluent NHibernate we can create an abstract mapping class for our DomainEntity from which we derive all entity mapping classes. The following code would give us the same result as the XML mapping files shown above:

DomainEntityMapping:

public abstract class DomainEntityMapping<TDomainEntity> :
ClassMap<TDomainEntity> where TDomainEntity : DomainEntity
{
    protected DomainEntityMapping()
    {
        Id(entity => entity.Id, "Id")
            .GeneratedBy.GuidComb();
 
        OptimisticLock.Version();
        Version(entity => entity.Version)
            .TheColumnNameIs("Version");
    }
}

CatalogMapping:

public class CatalogMapping : DomainEntityMapping<Catalog>
{
  public CatalogMapping()
  {
  Map(catalog=> catalog.Name, "Name");
    }
}

CatalogCategoryMapping:

public class CatalogCategoryMapping : DomainEntityMapping<CatalogCategory>
{
    public CatalogCategoryMapping()
    {
        Map(category=> category.Description, "Name");
    }
}

This way,  I can specify the mapping configuration for Id and Version in a single place which is really nice.

Mapping Tests

This is probably my most favorite feature of Fluent NHibernate. Given the fluent mapping configuration for the Category class shown earlier, the following test checks whether this mapping is valid or not:

[TestFixture]
public class When_verifying_the_class_mapping_of_a_catalog
    : NHibernateSpecification
{
  [Test]
  public void Then_a_catalog_object_should_be_persistable()
  {
   new PersistenceSpecification<Catalog>(Session)
          .VerifyTheMappings();
  }    
}

Running this test results in the following SQL statements being executed to an in-memory SQLite database:

NHibernate: INSERT INTO "Catalog" (Version, Name, Id) VALUES (@p0, @p1, @p2); @p0 = '1', @p1 = '', @p2 = 'c52126cb-f11e-47e4-a481-9bc600134d39'
NHibernate: SELECT catalog0_.Id as Id1_0_, catalog0_.Version as Version1_0_, catalog0_.Name as Name1_0_ FROM "Catalog" catalog0_ WHERE catalog0_.Id=@p0; @p0 = 'c52126cb-f11e-47e4-a481-9bc600134d39'

The following code shows the NHibernateSpecification base class for all my database tests. The code in this class deals with setting up the in-memory SQLite database and building the required schema based on the mappings. The Fluent NHibernate framework gives some really nice support for this as well:

[TestFixture]
public class NHibernateSpecification
    : Specification
{
    protected ISession Session { get; private set; }
 
    protected override void Establish_context()
    {
        var config = new SQLiteConfiguration()
            .InMemory()
            .ShowSql()
            .ToProperties();
 
        var sessionSource = new SessionSource(config, 
            new RetailerPersistenceModel());
        Session = sessionSource.CreateSession();
 
        sessionSource.BuildSchema(Session);
        ProvideInitialData(Session);
 
        Session.Flush();
        Session.Clear(); 
   }
 
    protected override void Dispose_context()
    {
        if(null != Session)
        {
            Session.Dispose();
            Session = null;
        }
    }
}

Fluent NHibernate really lowers the barrier for configuring NHibernate, which is a really big thing in my book. I must admit that I was a bit sceptical at first, but now I noticed that I'm having a hard time going back to the standard XML mapping configuration of NHibernate itself. As Fluent NHibernate is still in an early development stage, some issues can come up. But my personal experience so far is that the user group is very responsive.

How Do I Learn

You may have noticed that I didn't get around to write that many blog posts over the last two months. While some of you may regret this, others would argue that the universe has been a much better place since then :-). Anyway, I haven't been picking my nose these last couple of months. I've been working on a small sample application (which is still very much work-in-progress) to straighten out some of my thoughts about application design and architectures. While working on this "home project", I also get a chance to dive into some cool stuff like Fluent NHibernate, StructureMap, DSL's, etc. While I've been having fun, I completely neglected to write blog posts. That's something that I definitely want to improve over the next couple of months.

Anyway, back to the point that I'm trying to make here. The only way I can learn is by actually doing development work, whether its as big as a two year project or as small as a Code Kata. In order to become a software craftsman someday, I need to practice. Lots and lots of practice.

I also learn a lot from reading books, articles, blog posts, watching screencasts or video recordings from conferences and last but not least by reading code from respectful open-source projects. But in the end, they only sharpen my theoretical skills. In order to really challenge my thoughts, I need to be practicing.

Practice is what makes people craftsmen in other fields as well like surgeons, plumbers, repairmen, etc.. But for some reason, developers think that they can sit back, write code from nine to five and muddle on. While there is a time and place for everything in our lives, this particular attitude makes that the state of our profession can be much compared to the dark ages. We need to become better at what we do and who we are.

Somehow related, I completely agree with this blog post from Uncle Bob where he talks about being responsible for your own career.

YOU, and NO    ONE ELSE, is responsible for your career. Your employer is not responsible for it. You should not depend on your employer to advance your career. You should not depend on your employer to buy you books, it’s great if they do, but it’s not really their responsibility. If they won’t buy them, YOU buy them! It’s not your employers responsibility to teach you a new language. It’s great if they send you to a training course, but if they don’t YOU teach the language to your self!

Every book I've ever read about software development is a book that I bought myself from my own money. All the magazines I'm subscribed to, I pay from my own pocket. I'm responsible for my own learning, and I'm willing to invest whatever it takes to accomplish that. Whenever I want to learn something new, I'm not waiting for my employer to give me an opportunity. I make my own opportunities!

I realize I'm a bit late for the previous Butter's Monthly Bone. I can only hope that Butters won't eat me alive ;-).