What's hot ? (and I mean really ...) - scroll down for more
1).  Code Templating - advanced usage of delegates & generics: my slides & demos are available for download! CodeProject article is also available.

2).  My series "TDD in the eyes of a simpleminded" is in progress(including code!): preface, part1, part2, Q&A 1, Manual Stub .vs. Mock Stub

3).  TDD Workshop: SeeCompass v0.1 and v0.2 are out.
 Tuesday, December 19, 2006

(Before you start - give a look at C# and XML Source Code Documentation)

So you build up a nice API that everyone can use but you want to provide nice, IntelliSense-enabled comments along with your magical code right?
Let's say I have the class Logger in my "Infrastructure" dll:

/// <summary>
/// Our logger....
/// </summary>
public class Logger
{
   /// <summary>
   /// Log the given message...
   /// </summary>
   /// <param name="messageToLog">The message to log.</param>
   public void Log(string messageToLog)
   {
   }
}

Now, my clients(e.g other teammates) want to use this logger. Adding a quick "File Reference" to the dll and they are good to go. This is great _but_ they also want to see the comments I provided as they type (IntelliSense in action baby). Surprisingly enough, they will _not_ see it "by default":

NoCommentOnLogger.gif

As you can see (well, not see, but that's my case) - we don't see the class comment "Our logger...". The same goes for our Log method:

NoCommentOnLogMethod.gif

Where are my comments ?!!?

Well, it turns out that you should make a small change to make it alright. Say hello to "XML Documentation file". Open the Project Properties, under the "Build" tab there is a little checkbox named "XML Documentation file" - make sure it's checked and you're done!
All you have to do is to recompile the dll and add the reference again (e.g remove & add, Dumb, but works) or manually copy the generated xml file to your bin directory (if CopyLocal = true).

CommentOnLogger.gif     

CommentOnLogMethod.gif

 

Conclusions:

You should always make sure that "XML Documentation file" is checked!
Why providing comments if no one can see them (unless you have access to the code and you make a "Project Reference").

I'm not sure why Microsoft made this checkbox unchecked as default.
Am I missing something here?

Posted by Oren Ellenbogen 
19/12/2006 02:07, Israel time UTC+02:00,     Comments [2]  | 
 Friday, November 10, 2006

One of the keynote that my manager took from a clients tour in the US, jumped to my eyes: "100% of the users want to take actions in order to solve problems with the product. They are mad at us for giving them poor general error messages". He followed his sentence by "they don't know what to do after seeing a message 'two ways communication failure' or 'unable to retrieve results for X'". I took a pause and thought about this request and really started to think about how can we write better errors for our clients - errors that will ENABLE the users to solve bugs on their own!

After spending about 2 hours throwing ideas on my white board at the office, I came to the simple conclusion that its.... completely feasible!

Softwares contain bugs in it. You can hire the best programmers, the greatest QA guys, automate your testing, you name it. At the end of the day, your release will contain (more than one or two)bugs. So the problem is that the users can NOT do anything in order to solve those code-related bugs, right? Well, I really hope so because I really like my job. but how can we, the developers, give the user helpful error messages that will guide him to solve the bug that just happened or at least make him feel like one of the R&D team?

I decided to split the bugs into two categories:

  • Bugs that are solely code related: I'm sorry, but unless the user will have access to my source, he won't be able to make the fix. Now, who the hack wants to give the users access to their code? No matter what you show to the user, you know that he can't help you solving the problem right now. I believe that you can make him feel like he's helping solving the problem right now. here is my solution for that scenario:
    • Show the user a simple "We sorry but it seems that an error occurred in our engine. We managed to log the error and our best guys are working on it! BUT, we need your help in order to make this bug go away FAST, will you help us?".
    • After this message, show a little "form" with the title "Want to help us fix this bug quicker?" that will contains the following fields:
      • A short description of the form - just a label - "Please help us reproduce the actions you did so we will be able to fix this bug as soon as possible. We know that you have little time, if any, so we did most of the job for you by. It won't take more than 30 seconds starting now..."
      • Bug title (write the action the users tried to do as default - for example "Edit user's account").
      • How serious is this bug for you: a simple select-list from 1(it bothers me but it's not that important) to 5(I can't work!).
      • Bug description (leave it empty) - let the user know he can leave it blank.
      • How to reproduce this bug (here is the catch: you'll need to record the user actions in order to be able to do this) - write all the steps that the user did before he saw this bug. Let him edit the text with the flow (maybe he could add some value). Now, it's critical that you'll supply a good record mechanism as the user don't want to work for you. If filling this form will take more than half a minute, forget it, he won't help you.
      • BIG button - "I'm done, send it away".
    • The message will be sent to the system administrator if the network is local or to the support service if the network is connected to the Internet. Attached to the user's message you can add your personal log info (that depends on the application architecture of course, if you have Internet application you can log everything on the server anyway).
    • IMPORTANT: If the user sends the bug "help" form, and the bug solved quicker because of a good "how to reproduce" by the user and it was important to many users of your software - reward him and notify about it to the rest of the community (of your software). We want to let our "QA users" the incentives they deserve. I believe that letting the user "make some action" in order to help fixing bugs is better than just showing him "an error occurred, please contact your system administrator for further details". (btw - who came with that fucked up idea that the world adopted so quickly?!)
  • Bugs that are configuration related or business related: Hey! we have a chance here to make our users dream come true! there is a good chance that they CAN fix the problem by their own two hands. If the error happened due to Foreign Key issues, for example - the user is trying to delete a record that is referenced by other records, tell him that he needs to delete "X, Y and Z" (give him links that those records) before deleting the current one and explain why(the user's knows nothing about database or software "logic"). If it's something the user forgot to do, meaning the business flow is incomplete, tell him what he needs to do NOW and direct him (supply links or automatically direct him the the current place\position). If the current session of the user was ended so you can not save his form, try to save the user's time and save the form into the cache, let him log-in and then direct him to the previous page he was at and fill the page from the cache for him. Can you imagine how grateful he will be? If the user made a configuration mistake and gave bad data so now he can't send e-mails or run some process - analyze what went bad and give him a proper message. Avoid general messages on those scenarios like "SMTP error..." or "unable to delete the row" just because he forgot to fill some not nullable field. What you are required to do is analyze the StackTrace of the exception and to match it with the recorded flow (as I mentioned in the previous category) and try to provide a really good action items for the users. Let me tell you this, users will appreciate your effort in giving them a full details about what went bad and how they can play a part of the software developers and make the software better.

Most importantly, don't show developer errors to the user just so he could call you(or your service) and say "Hi, I'm a customer of yours and I've got a strange error 'SqlException: bad syntax in line 291 near ;'" ;-).

Posted by Oren Ellenbogen 
10/11/2006 04:48, Israel time UTC+02:00,     Comments [0]  | 
 Wednesday, November 01, 2006

My company, Mercury, is looking for sharp minds with endless passion for code and great creativity. If you consider yourself that sort of a guy and you're looking to work with the very best in the industry(my promise), please contact me(oellenbogen at mercury dot com) and send me your CV.

btw, I have no desire just to pass CVs between my site readers to my company. I would talk with each one of you(and ask you some interesting questions to see if you have the spark) that will pass me his CV before forwarding it to our HR. In addition, if you want to talk with me about "how is it to work there?" or any sort of question you might have about working at Mercury, feel free to drop me a note. I'm eager to join the best of you guys to our company.

Posted by Oren Ellenbogen 
01/11/2006 04:55, Israel time UTC+02:00,     Comments [0]  | 
 Friday, October 13, 2006

Wow, it's an Agile world we're living in isn't it ?

Could you guess how many hits you will get by searching "Good Agile" in google? about 12 million!! "Being Agile", "Agile principles", "Agile stories", "Agile practices", "Good Agile, "Bad Agile" - millions of books and articles out there for us to reach. Buzzwords addicted as we are, we try it all. We pair programming, we work in short iterations, we drop features early and receive early feedbacks, we combine our developers with our QA guys to create some sort of "Feature Team", we use cards, backlogs, big boards with colors, we Scrum, we XP. We practice. We succeed. We fail. We try. Still, a lot of people all over the world claim that Agile Development don't actually work and those methods cause more damage than good. Reading Stevey's post about Good Agile .vs. Bad Agile made me think about my definition for successful agile development. 

Do you ever seen StarGate? if not, it's really not too late to buy a DVD and catch up. In this great TV series, SG-1, the "main" team on StarGate, explore the galaxy through a series of Star-Gates, each one located on a different world, which allow them to move from one gate to another through some sort of wormholes that connect the gates together. Their job is to interact with other species, to establish alliances and to acquire new technologies. SG-1 is my definition for an agile team.

Let me introduce you to the team:

jack.jpg

Jack. A confident soldier and the ultimate manager - he will be the first one to take to bullet, always believing in his teammates and letting them do their job with full confidence. Improvise is his nature. His team are his family. He's the one that make the team glue together.

sam.jpg

Sam. The genius scientist of the bunch. Do you need someone that will write your Java paper for the university in alien dialect? Do you need to make your car a flying ship from two gums and a rope? Rummer has it that she wrote Skype in pure assembly just for the fun in it and that WCF was actually planned by her(Juval Lowey disagree, though). Never says no (I am naughty...) and always do her job in a professional matter, thinking two(thousands) steps ahead(the 100000 alien she killed concur).

daniel.jpg

Daniel. "I can talk 10293740447303^2 languages in 2827349*3 different dialects" guy. If you have a beloved dead uncle whom you're dying to talk with, page Daniel and he make it happen. Got a book from 1700BC in Chinese that you are really eager to read, he'll translate it into English in an hour. A passionate guy that manage to calm the team under fire an to make some sense of Jack's nonsense.

tealc.jpg

Teal'c. The muscles. Teal'c is an alien that joined the team after being slaved to the "gods"(high rank politician with some impressive gun power) in his home-world. He can kill a nation and shave simultaneously. Brave warrior that brings the confidence the team requires during hard times. If you are an AC Milan fan as I am, he is kind of Gatuso - you thank the lord that he's on your team.


You know why SG-1 is the ultimate agile team? because of the people in it and the way the complete each other. See, you can learn the tactics, get the right tools but without the right men in the right position, you are as good as dead. From my experience, there are bunch of actions you can do to make your development process as agile as possible:

  • Invest time in developing inner tools for your workers. You need tools to help you code(good IDE), to control your source, to set up a Continues Integration environment, to perform Daily Builds, automatic Unit Testing and Code Coverage, to run automatic UI and Sanity tests. You will want to easily create setup files and deploy them on various testing environments all in a single click. You want fast feedback that your product is stable each and every day.
  • Challenge your people on daily basis. Pair them together on tasks that they can teach&learn from each other.
  • Give your team members the "small" stuff they need (bigger space, another screen, better chair, more food, whatever!).
  • Praise your workers. Glorify them. If they give their best - they deserve that.
  • Treat each and every one differently.
  • Hire the best people and the best people only. yes, it is worth it. one superstar developer is better than 5 mediocre ones. Don't believe any book or any poor manager that claims otherwise. Hack, don't trust my words, what do I know anyway? Instead, let's all read 100 books of XP and Scrum, miss the deadlines, release crapy code and hate our jobs. We can always blame the management. Superstar developers will build tools that can replace 10 mediocre programmers, so let them do it and give them the stage they need. Superstar developers make your company a place worth working for. Best people bring the best with them. Now, isn't it worth paying some extra for those guys? Don't worry, you will get your $$$ back, I promise.

So agile, in my book, is the confidence you have in your teammates and the greatness of your people and your tools. Without the best people, don't bother doing the rest. at least don't expect for "agile" development. The best you'll get will be Agile Development and that's suck isn't it?

Posted by Oren Ellenbogen 
13/10/2006 04:41, Israel time UTC+02:00,     Comments [2]  | 
 Saturday, October 07, 2006

As I mentioned before, Pasha and I are in the process of developing a small application and we still thinking about where to place our Source Control repository. At the beginning, we thought about hosting it on my computer but after a few hours of trying to work with SubVersion (I need to read a little, I thought it would be simpler) configuration and some attempts to configure VSS 2005 I realized (actually, Dror realized, I just nodded) that my router is not suit to serve as a host. We now have 2 solutions: (1) order a new router (about 100$), buy a static IP and configure it properly (as I told Dror: "I'm a code hacker, not a network hacker") which means a lot of time by my side(and 4-7 days of waiting for the router to arrive) or I can (2) pay for a repository server and let someone else take care of static IP, and the configuration. Oren Eini proposed working with www.hosted-projects.com which seems like a nice service - they provide SubVersion & BugTracking for a nice fee. Lacking a solid Source Control really keep us from coding in full speed, so it's urgent to set up our repository in the next couple of days. Any ideas ?

p.s - no, it's not Open Source :-).

Posted by Oren Ellenbogen 
07/10/2006 05:10, Israel time UTC+02:00,     Comments [1]  | 
 Wednesday, October 04, 2006

A few days ago a teammate asked to me to help him with a little some-some. This some-some was an event delegation problem (some-some sounds better) that she wanted to implement and wasn't really sure how. The scenario is quite simple, we have a few classes and one of the classes is a little “deep” (deep object graph), meaning:

object of type A 
object of type B 
object of type C 
   inner member of type class D 
     inner member of type class E
      inner member of type class F – known as f1

Now, the value f1 can change, and while it does so, we need to notify the rest of the instances (a1,b1,c1,d1,e1) of that change and provide them some extra details about the change itself. One solution is to add an event to all the classes, register from each one to the inner member event and then f1 can trigger the change to E which will trigger the event to D and then to C->B->A. In short - delegate the call all the way up and around. It seems like a hard job to me - too many places to change, too many events to declare which are not really necessary. I came up with a static Events Notifier solution. Think of it as a repository for registering and triggering events. Here it goes:

public static class EventsNotifier
{
   public static event EventHandler<Status> StatusChanged = delegate {};

   public static TriggerChangeStatus(object sender, Status s)
   {
      StatusChanged(sender, s);
   }
}

Now each class, in its constructor, can register to EventsNotifier.ChangeStatus event and my f1 can call EventsNotifier.TriggerChangeStatus(this, new Status(...)); which will notify the rest of the objects. I know, it's not a perfect solution, but It has its pros. What would you do ?

Posted by Oren Ellenbogen 
04/10/2006 09:42, Israel time UTC+02:00,     Comments [3]  | 
 Monday, October 02, 2006

Let's say we have an entity named "Blog" that has many "Post"s in it:

[ActiveRecord("Blogs")]
public class Blog : ActiveRecordValidationBase<Blog>
{
   private IList _posts;
   // ... snipped ... 

   [HasMany(typeof (Post), 
      Table = "Posts"
      Lazy = true,
      ColumnKey = "BlogId")]
   public IList Posts
   {
      get { return _posts; }
      set { _posts = value; }
   }
   
   // ... snipped ...
}

Configure your web application to support lazy loading:

  1. Use the isWeb="true" attribute in your web.config file - look here for "how to".
  2. Open a SessionScope at the beginning of each request - look here for "how to".


Now, How do you know if lazy loading is (really)enabled:

Blog b = Blog.Find(1);
bool isInit = NHibernateUtil.IsInitialized(b.Posts);

If isInit shows true, then lazy loading wasn't enabled and you need to make sure you didn't miss anything. if it shows false - lazy loading is on!

Thanks for Ayende Rahien for pointing on NHibernateUtill, this can be quite handy.

Posted by Oren Ellenbogen 
02/10/2006 08:01, Israel time UTC+02:00,     Comments [6]  | 

Myself and Pasha are now starting to build a little thing we came up with and we thought that it will be a good idea to use this little baby to learn about the new technologies out there. But you can't learn everything at once right? so we decided to start with Atlas. In addition, we want to take advantage of some sort of infrastructure to perform the common tasks we are all familiar with while developing an application like (1) Data persistence (2) Lazy Loading (3) Caching (4) Data Validation (5) Nullable fields (6) Transaction support and their partners (7) Authorization&Authentication (8) Logging and such. Looking around the net, it seems that ActiveRecord (I see it as an abstract shape of NHibernate, one that makes you smile while mapping your entities and querying them instead of pulling your hair in anger) which is part of Castle Project, support tasks 1-6 pretty damn good so it will be a huge part of my POC. I'm planning to share my insights with you, including the "How To", "Why To" and the complete source code of the POC which will include the skeleton of our infrastructure.

You can download the Castle version(Includes ActiveRecord) I use from here (It is from August 27th, 2006).

Posted by Oren Ellenbogen 
02/10/2006 07:44, Israel time UTC+02:00,     Comments [0]  | 
 Wednesday, September 27, 2006

Remember "Lnbogen test for Google's rating, the target: Oren Cohen"?
Well, I thought it will take about 2 weeks, but google managed to surprise me. Looking for "Oren Cohen" in google.com will give you my post as the 18th result. Oren is now thinking about publish his pictures\sites in my blog. I guess I should start thinking about a pricing model ;-), I need to provide some food to my kids, support 15 wifes, etc. It can get quite expensive you know...

The proof (you are welcome to search for "Oren Cohen" at google.com yourself, of course):

OrenCohenBetSmall.gif

Posted by Oren Ellenbogen 
27/09/2006 05:13, Israel time UTC+03:00,     Comments [0]  |