Ayende @ Rahien

Refunds available at head office

Handling nullable datetime in NHibernate : The Interceptor

System.DateTime is a value type, and as such, cannot be null. The default value for DateTime in .Net is DateTime.MinValue, which equals to 01/01/001 00:00. The problem is that SQL Server's dates start at 1753, or there about.

This is usualy solved in .Net 2.0 using Nullable<DateTime> (or DateTime? in C#), but my "entities" are messages to web services, and are generated from WSDL, so they lacked this nice feature. I also didn't realize that some of the DateTime values were nullable until pretty late into the game.

After a lot of head scratching, I came up with this solution, which utilizes NHibernate's IInterceptor capabilities. The interceptor allows to get the raw data before it is loaded and after it is saved, and interfer with it. Using that, I got this DefaultDateToNullInterceptor:

public bool OnFlushDirty(

    object entity, object id, object[] currentState, object[] previousState, string[] propertyNames,

    IType[] types)

{

    MinValueToNull(currentState, types);

    return true;

}

 

public bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)

{

    MinValueToNull(state, types);

    return true;

}

The OnSave() and OnFlushDirty() methods are called before the values are saved or updated (respectively). The MinValueToNull() method is very simple, it replace all instances of DateTime.MinValue with null, like this:

private static void MinValueToNull(object[] state, IType[] types)

{

    int index = 0;

    foreach (IType type in types)

    {

        if(type.ReturnedClass == typeof(DateTime) &&

           DateTime.MinValue .Equals(state[index] ))

        {

            state[index] = null;

        }

          

        index+=1 ;

    }

}

All that was left was openning the session with the interceptor, and I was set.

Spot the WTF

Thankfully, I haven't run into this one yet, but can you spot the WTF here?

Tags:

Published at

Distributed Applications Failure Points

The worst part of building a distributed application is that you get different state in different parts of the system. Let us take a look at a simple message passing application, and the issues there. At the end of the day, each and every message should arrive once, and exactly once. I am assuming that it is not possible for the message to be corrupted in transmissions (The TCP/IP stack in general makes sure that you won't see those messages).

The simplest model is where everything works out great:

(Image from clipboard).png

A common scenario is that the sender failed to send the message:

(Image from clipboard).png

A simple resolution is sending the message again, and again, until you get an OK reply back. But then there is the dropped reply scenario, the reciever got the message, but the reply was dropped. As far as the sender knows, the reciever never got the message:

(Image from clipboard).png

A naive implementation on the reciever side will lead to the duplicate message scenario, but a slightly less naive implementation, which detects and errors on duplicate messages may result in a lot more headaches in the end, consider this scenario:

(Image from clipboard).png

The sender never recieves an OK reply for his message, so it will send it to the end of the days. The reciever got the message the first time and replied just fine, but the sender persist trying to give it duplicate data, which means that it keeps returning error messages back.

A good way to prevent that is to check before sending, like this:

(Image from clipboard).png

Assuming that we always keep this semantics, a failure at any points of the road never leads to losing messages or duplicating them. I tried, but I can't think of a way the sender will think that the reciever got a message when the reciever didn't get it.

Just to point out, the scenario above happens all the way up from TCP. This is a relatively simple scenario. More interesting ones include ordered messages, and two ways communications.

Hope you liked the pretty pictures.

Tags:

Published at

Server side vs. Client Side

I just had a discussion about server side programming complexity vs client side programming complexity.

I hold the view that doing client side programming in an order of magnitude harder than doing stuff server side.

I was shocked to see this proof of my correctness:

(Image from clipboard).png

And yes, I realize this is a falacy.

Tags:

Published at

Clarifying interaction based testing

One of the big advantages to state based testing is the clearer error messages, like this:

Assert.AreEqual(5, collection.Count, "Expected to have 5 broken rules as a result of XYZ");

Using interaction based testing, you usually can specify much less information:

validationResult.AddBrokenRule(null);
LastCall.IgnoreArguements().Repeat.Times(5);

Is this a setup code? Is this the expected result of the test?

Who knows? Certianly not me in tree weeks (or months) times, when this test is broken and I need to figure out why.

I am thinking about adding a Message construct to Rhino Mocks, which wil allow to specify messages that clarify the intent of the developer. Something like this:

validationResult.AddBrokenRule(null);
LastCall.IgnoreArguements().Repeat.Times(5)
   .Message("Expected to get 5 broken rules");

There are some implementation issues (what happen when you get called too much, for instnace), but they should be workable. But before I try to add this, I would like some thoughts about the value of this feature.

Book Review: Applying Domain-Driven Design and Patterns


Applying Domain-Driven Design and Patterns: With Examples in C# and .NET

Couple of disclaimers before I continue:

  • I got a free copy of this book to review.
  • I am probably not in the intended audiance of the book.

Nearly a month and a half ago, I posted my initial impressions from this book, which were good (even if it didn't come out like that). It took me quite a bit more to read it than the usual, mainly because I was swamped with work.

Anyway, the book declares itself as a guide to develop sofware using DDD. In fact, it covers much more ground than that, including patterns, inversion of control, testing, high and low level design, and more.

The overall tone of the book is very... relaxed. It felt at times like I was reading a long blog post, which meant that I had no problem with reading it on/off for a long time. The material is presented in a very approachable way, including a lot of details and explanations about what is going on.

I particularly liked the side notes where there are critiques on the code, some from Jimmy and some from other reviewers (This approach had this and that disadvantages, but I am using it because of the following reasons..., etc).

The first part of the book is an introduction to the concepts that are used throughout the rest of the book, patterns, TDD, domain concepts, etc. This was mostly repeating stuff that I knew, but it is a point to Jimmy's point that he managed to present the material in a way that was interesting even when I already knew what he was talking about.

The second part is where I consider the meet and bone of this book, covering how to apply DDD. The general architecture that is presented is similar to what I consider as ideal at the moment, and close to what I am trying to build in several applications at the moment. This part also straighten out some concepts that I didn't quite manage to understand from Evan's DDD book. Specifically, the relationships between the domain model and services and how to use them. I got several good ideas from this part, and it is responsible for my NHibernate Query Generator.

What I didn't quite like is the 7th chapter, about business rules. Partly this is because I'm currently invovled in an effort to implement fairly complex business rules implementation, and I don't think that the approach presented can hold in the face of the more complex scenarios. (Think of a case where you got heirarchical rules that are time dependant executing over a domain model that is timing sensitive. If you said Yuck!, I agree ;-)).

The forth part is talks about persistance, how to prepare to it, and how to implment it using NHibernate. I mostly agree with what was preseneted, and I was very surprised to learn new (and exciting) stuff about NHibernate (did you know that the mapping can declare Assembly and Namespace attribute seperatedly?).

The last part talks about moving the design forward, and how to take the domain design into the UI layer, and give the users a chance to take advantage of that as well.

What I didn't like:

Jimmy tries hard not to fall into the trap of using a specific product to show the concepts he is talking about. While it is a good approach in general, I felt at times that he is attempting it too hard. It might have been preferable to show the concepts using a certain tool, and mentioning how other products are solving similar problems.

There isn't any real refinement of the domain model as a result of new requirements or better understand of the client's model. The changes presented were changes mostly driven by technical decisions, not different way to understand the model.

Evans' DDD book made use of the shipping industry, with the difference being changing from focus on moving the cargo around, to moving the legal responsability for the cargo. I didn't see any such example in the book, and this is a core part of DDD.

Conclution:

I would like to work on applications developed using the principals shown in this book.

I don't think that the title is doing the book justice. It is not nearly about DDD as about the whole approach to develop applications.

I tried to pinpoint who exactly will not benefit from this book, and I couldn't quite put my finger on it. If you are currently busy building application based on Evans' DDD, with full usage of TDD and are familiar with Fowler's Patterns of Enterprise Applications, you will probably not get much out of this book.

If you are a "standard" .Net developer, and by that I mean that you mainly used Microsoft's prescribed tools and practices*, you will get quite a bit of insight from reading the book. I intentionally do not limit this to intermediate (whatever that means) developers, since it is more about a shift in thinking than about the level of code required.

I am certainly going to circulate this book to other developers in my team.

Great job, Jimmy.

* And I don't need to tell you what I think about most of them, do I?

Tags:

Published at

IRepository(Of Customer) vs. CustomerRepository

Using IRepository(Of Customer):

Customer[] customersWithUnpaidOrders = repository.FindAll(@"select c from Customer c, Order o 
where o.Customer = c and o.Status = OrderStatus.Unpaid"
); 

Using CustomerRepository:

Customer[] customersWithUnpaidOrders = repository.GetCustomersWithUnpaidOrders();

The difference is the level of abstraction that is used. In the first case, the code define the question explicitly, using the generic repository to pose the question. In the second, it is the CustomerRepository responsability to get the data.

The first is much more flexible, but it is harder to test. The second is much easier to test (but require better integration testing to check that it the repository is actaully doing its job), and is more intention revealing.

Don't get greedy with online ads

I just spent four minutes configuring AdBlock to remove annoying ads from this page, I don't have an issue with normal advertising, but naything that blinks, jumps, etc is annoying.

I am not going to pay positive attention to stuff that annoys me. The end result that I don't know what the ad was about (it was big and black and green, that is all), but just about any ad server from this page is forever blocked on my browser.

C# Riddle #5

Following Alex's post about traps in interviews, I thought about posting bits of code that I won't use in interviews. Mostly because I don't think that it is fair to the interviewee. I can think about crazy usages to langauge features, and not in a good way.

Consider the following peice of code (which is valid C# 2.0):

public IEnumerable<Predicate<Customer>> ValidationPipeline()
{
 yield return delegate(Customer c)
 {
  return c.Name != "";
 };
 
 yield return delegate(Customer c)
 {
  return EmailService.IsValid(c.Email);
 };
}

How would you use this method, and what is wrong with it?

The Curse Of The Infrastructure

If at all possible, minimize any dependencies on infrastructure that you have in your applications. The more dependencies on infrastructure you have, the less freedom you can get.

I define infrastructure as anything that I can put on my laptop and use without being connected to any network whatsoever.

Some examples of infrastrcuture bound applications are:

  • Domain dependencies - the application must contact a domain controller for autentication, authorization, or just for the hell of it. (The reverse is also true, the application must not be run from a computer which is part of a domain).
  • Forced distributed application - each part of the application cannot (under pain of crash) be run from the same computer.
  • Each part of the application require radically enviornments (server OS vs. client OS, windows/linux, etc)
  • The application uses Oracle.
  • Using very large DB (Greater than 1GB) or multiply thereof.
  • Requiring an exotic component (AS400 to hold the configuration for the application, for instnace).
  • Requriing connection to a remote server accessible from a single point only

An infrastructure bound application is:

  • Harder to deploy.
  • Harder to test.
  • Impossible to develop in a disconnected environment.
  • Usually impossible to run except where it is was developed (or deployed with much effort).

I guess you know my opinion about such applications. I hate to be forced to work from a specific place, because it usually means that I can't "steal" work time on it when I am away from the office.

Love the debugger team

I have quite a bit of rants against several teams at Microsoft, but I wanted to dedicate this post to the VS debugger team, which has done a superb job in VS 2005. Maybe it has to do to the fact that I am a debugger user and not a developer, but so far the only issues that I had with the debugger are stuff like "You didn't configure E&C in the option panel, etc".

This post was prompt by a fact that I accidently discovered recently. You can step into the web service code from the client code, if it is on the local machine. Just to give an idea about the eneromosity of this feature, this means that you automatically attach yourself to another process, find the correct place to go, and go there. I would have never thought of trying this, because "obviously" this would work.

 

Tags:

Published at

On Interviews and Traps

Alex is making a good point about interviews questions and traps. Interviews questions are not real code, at least not at the first stages. Most of the stuff that I intend for interviews is not going to get somebody called on the carpet if I get to it on production code.

In an interview, I need to be able to judge someone's technical skills very quickly, and hopefully accurately. I can spend a day pairing with a guy and then give a highly accurate view of his/her abilities, mindset and match for our team. I can't do that in half an hour to an hour (the span of most first-stage inteviews).

The point of questions like that is not neccecarily to get the correct answer, it is to discover areas of knowledge. If you can't answer this question, you don't have a lot of experiance in C based languages, period.

If you need to think before you answer this question, great! I want people who take a step back when they encounter this code. But if you programmed in any C based language for any significant length of time, you would know what the meaning of postfix ++ operator, and what it should do.

If you can't figure out the answer, but can decompose the steps taken by this answer, than is fine as well. But this question points fairly accurately to the amount of knowledge that you have in the language per-se.

Other questions that I ask include "What is the difference between value/ref type?" and no one told me yet that ref types are on the heap, and value types are on the stack. I was told that value types are not changes, are copied, etc. That question is another good indication for the amount of knowledge that a person has.

"Is string a ref or value type?" - this one almost everyone gets wrong.

Part of the problem is that I refuse to be limited to what Microsoft supplies, which means that I need to be able to judge what they will be able to learn if/when we hire them. If they can't think and they program by rote, I don't want that. And asking questions that require thinking is a good way to discover that.

Tags:

Published at

Taking the measure of a developer

Continuing on the interview stuff, here is something that can tell you quite a bit about a developer. Given the following error, what do they do?

(Image from clipboard).png

Here are a couple of options:

  1. They tell you: "I can't get it to work, it keeps failing and I don't know why."
  2. Look into the inner exception.
  3. Googles the exception message first, and give up if the first result doesn't show anything relevant.
  4. Look into the inner exception, google that, and fix the problem.
  5. Fix the error after reading the message
  6. Look into the inner exception and fixing the problem.
  7. Download and install the kernel debugger and then they start digging

If they can't pass this test (and if you are reading this post, I sure do hope that you know what of the above is a correct response), they don't hire them.

Great Interview Question

Here is something to add to the indicators list:

What does the following do?

selected = selected++;

If they can't figure this out, you got a problem.

More interesting question may be:

Contrast the results of the following two operations:

  • selected = selected++;
  • selected = ++selected;

[Via The Daily WTF - Sidebar]

Things that will make me come after you with a BIG stick: Part 1

For some reason, I get to see a lot of WTF?! in the field, and I think that this is about time that I do something about it. I'm going to start a series of posts about the stragest stuff that I see.

Today, we have the New Data Model to observe. As you hopefully know, there are three (and only three) ways to create associations in the database, one to many, many to one and (using an association table) many to many. Trying to invent new ones will cause pain.

Take for example this table diagram:

(Image from clipboard).png

It may not seem bad to you until you dig a bit deeper and realize that both Items.Id and Items_Security.ItemId are primary keys, and both are Identity Columns!

Programmer's Bill Of Rights

Jeff Atwood published the Programmer Bill Of Rights, which I like.

Of the list, I currently don't have is #3 (mouse & keyboard that I want) and that is because I have a laptop, and I refuse to increase the time it takes to set it up for work.

Tags:

Published at

Delays...

This keeps popping up, take a look at the times I have been hitting the snooze button.

(Image from clipboard).png

And those are just the things that I keep track of in Outlook...

Reading the SSCLI Comments

I'm browsing through the Shared Source CLI at the moment, for no good reasons...

I found the following comment in the System.String implementation...

**Action: Many years ago, VB didn't have the concept of a byte array, so enterprising
**        users created one by allocating a BSTR with an odd length and using it to
**        store bytes.  A generation later, we're still stuck supporting this behavior.

Good to show a sense of humer in the code, I always says.

Did you know that the CLR has a week reference hashtable? (Marked internal, of course, so you will not be able to use that ("Why, you horrible little man, why would you want to use a weak hashtable? Infidel")

You just love Clipboard Inheritance, don't you?

The generic Dictionary was copied from Hashtable's source - any bug
fixes here probably need to be made to the generic Dictionary as well.

(To be fair, I can't think of another way to do it)

I like this quote too:

(Knuth's Art of Computer Programming, Vol. 3, p. 528-9)

Ah, the smell of the compiler breaking in the morning...

Nothing like making a refactoring that goes through 140 compiler errors that I need to handle manually. Right now my least favoriate class in the framework is System.DateTime.

Nothing like adding a forth dimention to your application to make you realize how much you hate time.

On the other hand, I did get to create an OutOfTimeException which are going to provide me with hours of fun...

Tags:

Published at

I like this statement

I was writing a comment and suddenly noticed this, I liked it so much that I had to post about it;

DataSets also put you firmly in Data Is King camp, and it means that you code turns into a set of operations on the data, instead of a set of interacting objects.

Watching the logs run with log4net

Logging is fairly critical to many applications, and it is especially critical when you are trying to understand in a complex application. I'm using log4net for logging, because it is so simple to start with and it can scale up to very complex needs.

The problem that I had was watching the logs. Specifically, watching the logs run in real time. The application is heavily mutli threaded, and run as a windows service. It is pretty hard to get what is going on there unless you watch the progress of the logs. At first, I simply logged to a file, and read it in notepad. This approach doesn't really scale well.

Next, I tried log4net viewer, which is really simple to get working. Just start the application, and put the following in your log4net config:

<appender name="UdpAppender"

                type="log4net.Appender.UdpAppender">

       <param name="RemoteAddress"

                 value="127.0.0.1" />

       <param name="RemotePort"

                 value="8080" />

       <layout type="log4net.Layout.XmlLayout">

              <param name="Prefix"

                        value="" />

       </layout>

</appender>

Here is what it looks like:

(Image from clipboard).png

The problem is that it is very simple, and it has several bugs that I couldn't live with (specifically, it doesn't display the information correctly if you are using sorting or filtering).

I then turned to log4j's chainsaw client, which is far more impressive feature wise. This is a java UI client, but it is very sophisticated. Almost to the point of being of no use to me, actually.

First, you need to put this in your log4net config:

<appender name="UdpAppender"

                type="log4net.Appender.UdpAppender">

       <param name="RemoteAddress"

                 value="127.0.0.1" />

       <param name="RemotePort"

                 value="8080" />

       <layout type="log4net.Layout.XmlLayoutSchemaLog4j, log4net" />

</appender>

Then, create a file called log4net.config.xml with the following content:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration

       xmlns:log4j="http://jakarta.apache.org/log4j/"

       debug="false">

       <plugin name="UDPReceiver"

                     class="org.apache.log4j.net.UDPReceiver">

              <param name="Port"

                        value="8080" />

       </plugin>

</log4j:configuration>

On startup, the chainsaw will request a configuration file:

(Image from clipboard).png

Specify the location of the log4net.config.xml file that you creted previous, select don't show me this again, and click OK.

Then, you get the main UI, you need to click on the chainsawl-log tab:

(Image from clipboard).png

You should get a screen similar to this:

(Image from clipboard).png

The part marked in red is the loggers tree, which will become important in just a minute. Right now it displays just chainsaw' own internal logs.

Now, start an application that will log to the UDP Appender, and watch the tree on the right, here is how it looks like after I run a bit of NHibernate's tests:

(Image from clipboard).png

Right click on the part of the tree that interests you and select focus on '...'

You can double click on the tab header to get the tab in a seperate window (useful for utilizing screen real estate):

(Image from clipboard).png

Chainsaw how powerful filterring and coloring features, and it is pretty good in allow me to check what my application is doing in real time.

Tags:

Published at

Primitive are not datatypes - or how to make me scratch my head

This post hit a really sensitive point with me, Eber is showing some of the more complex forms of generics. Here is how he hold all the files in all the directories in all the computers

Dictionary<string, Dictionary<string, List<string>>> list = 
new Dictionary<string, Dictionary<string, List<string>>>();

I can't read code like this. I have a dictionary of a dictoary of a list. That is all fine and dandy, so far. The using code looks like this:

list[@\\Rhino][@"C:\Files"][5] 

The problem is that without knowing what this mean, I have no idea how to work with this. What is the first string, what is the second one, and what is the third one, for crying out loud?

Code like the above is opaque, is doesn't tell me what it is. A far better alternative would be something likes:

public class Domain
{
  public IDictionary<string,Computer> Computers { get; }
}

public class Computer
{
  public IDictionary<string, Directory> Directories { get; }
}

public class Directory
{
 public IList<string> Files { get; } 
}

This is a data structure that has a meaning. The client code looks like this:

domain.Computers[@"\\Rhino"].Directories[@"C:\Files"].Files[5]

Now I can read it without knowing having to know what the original author meant.

Yes, having generics can save us a bit of time in creating a new class, but you should ask yourself if this is worth losing the clarity of the code.

Tags:

Published at