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.
# Thursday, April 13, 2006

I've joined Microsoft Israel community so you can now find some of my post in this address:

http://blogs.microsoft.co.il/blogs/orenellenbogen/

I'll publish a few advanced post in Hebrew in the following month so stay updated.

.NET | Life
Posted by Oren Ellenbogen 
13/04/2006 07:08, Israel time UTC+03:00,     Comments [0]  | 
# Wednesday, April 12, 2006

I'm going to give a deep insight presentation about advanced usage of delegates, generics and anonymous methods at the next C# group meeting.

Please let me know if you're planning to come(drop me a comment), it will be nice to see some of my co-workers\readers\friends at my first lecture at Microsoft user groups.

The original excrept can be found here. (don't forget to register, free of charge, by sending an email to: ivcug at comconix dot com)

The Details:

Date:    Wednesday, May 17, 17:00 - 20:00

Place:   Microsoft Israel 

            Hapnina 2  (Amdocs Building)

            Ground Floor

            Raanana

+972 (9) 762-5100         

 

Parking available at the Kurkar parking lot. Proceed straight past the traffic circle and the parking lot will be on your right.

Topic: Advanced Use of Delegates and Generics

Lecturer: Oren Ellenbogen

 This lecture will not be just about Delegates or Generics, but it will combine those topics to show you how you can leverage to usability of those semi-new features. Oren will discuss the receiving of delegates as parameters and the implementation of abstraction in this methodology. He will tie the two topics together by refactoring(live!) existing code using a principle he calls “Code Templating”;  a coding method that allows running unique logic within recurrent code.

 Agenda:

  1. Looking at a "simple" scenarios of recurrent code
    1. Check if a value exists in a collection.
    2. Get the item index in a collection.
    3. Filtering a collection (get only some of the items based on a condition).
    4. Manipulating every item in the collection (string concatenation for example).
  2. Looking at "advanced" scenarios of recurrent code
    1. Querying the database.
    2. Exception handling.
  3. Discuss solutions for further abstraction in those scenarios.
  4. Introduce "Code Templating" – separating the unique code from the recurrent code.
  5. Before we start, getting to know our toolbox: generics & delegates
    1. What are they?
    2. Calling a delegate which was given as parameter – understand the benefits.
    3. Anonymous delegates\methods – how & why
    4. What's going on under the hood?
  6. Examples of Code Templating in .Net 2.0
    1. Handle those "simple" scenarios via List<T>.Find, List<T>. FindAll, List.<T>.Exists etc…
  7. Refactor (live!) the "advanced" scenarios, step-by-step.
  8. Code Templating - What do we gain? What can we lose?
  9. Q & A

 

Oren Ellenbogen is a Team Leader at SQLink's R&D Department. Oren's responsibilities and areas of expertise span from Analyzing and Designing Web Applications to developing innovative coding enhancement tools. Oren's project leading at SQLink involves all stages and forms from team leadership to high level consulting.

 Oren's years of developing experience cover a variety of languages including PHP, C++, VB6 and C#.

 Oren published a series of articles at codeproject.com, publishes a programming oriented blog and is an active member of several .Net architects forums.

 As always, although admission is free and you may attend without reserving a place, we kindly request that you notify us if you plan to attend so that we can be sure to have enough chairs and FOOD!

Posted by Oren Ellenbogen 
12/04/2006 05:00, Israel time UTC+03:00,     Comments [0]  | 
# Thursday, April 06, 2006

I sat with Mario today in order to figure out the best way to receive a "status" message from one of our business layer methods.

The task was clear:

We want to activate a rules validation method which will query the data and retrieve the missing operation(s) which are needed before the user can save his data. It is possible that the user have only one operation he has to do but it's also possible that he has to do N operations. We needed some sort of status combination.
In addition, if the validation passes - we want some sort of "Everything is OK" status.

Our options:

  1. Use ref\out parameter and fill a string variable. Concat error messages to that string and send it back to the caller. The method will return true if everything is good and false otherwise.
  2. Return the error message(s) as string. Again, we'll have to concat the error messages.
  3. Return a Bitwise Enum which will allow us to "add"\"remove" statuses.

Elimination process:

The main reason we quickly drop options (1) and (2) is the orientation of the error message(s). Sometimes, in act of pure laziness, we will print the error we've got from the BL method directly to the user screen. Some time passes by and the user gives you a call and says "Hey, I'm trying to save a user but it throws me an error like [Rule 1] is invalid... What the heck is [Rule 1] ?? I don't remember seeing it in the user manual!" and you'll reply "Wait a second, let me see... Hmm... if... else...not... Oh ya!! the bank account number you filled doesn't match the bank address !". See the problem here ?

Think about it - your business layer should return a "programmer oriented" message rather than "client oriented" message. If you'll return some sort of client oriented message from your BL - how would this work in multilingual application ? your BL would talk with some Resource Manager just to return the "correct" message to the user ? No. This is why you have Graphic User Interface layer. So we'll send a programmer oriented message from the BL back to our caller (for logging purpose), but wait, this will require our GUI to parse the string we've got from the BL method and format it for the client. Something like:

if (errorMessage.indexOf("Rule 1 is invalid") != -1 && errorMessage.indexOf("Rule 2 is invalid") != -1)
{
    // show "1). You must fill the user details. 2). You must fill the user paycheck"
}
else if (errorMessage.indexOf("Rule 1 is invalid") != -1)
{
    // show "You must fill the user details"
}
else if (errorMessage.indexOf("Rule 2 is invalid") != -1)
{
    // show "You must fill the user paycheck"
}
else
{
    // show "Save complete"
}

Yes, I can make some refactoring (constants, ToLower(), split) but no matter what I'll do - this code smells (terrible) !

Solution:

This leaves me with option 3. It would be great to ask something *like*:

if (status == ActionStatuses.InvalidRule1 && status == ActionStatuses.InvalidRule2)
{
   // show "You must fill the user details. You must fill the user paycheck"
}
else if (status == ActionStatuses.InvalidRule1)
{
   // show "You must fill the user details"
}
else if (status == ActionStatuses.InvalidRule2)
{
   // show "You must fill the user paycheck"
}
else
{
   // show "Save complete"
}

It's time to write some code, shall we ?

1). Let's define a bitwise Enum, so will be able to create a status combination:

[Flags]
public enum SaveUserStatuses
{
   OK = 1,
   BankAccountMissing = 2,
   WrongEmailFormat = 4,
   BankAccountMismatchBankAddress = 8,
   SaveFailed = 16
}

The only rule: if you need to add more values just double the previous value by 2.

2). In our business layer method, we'll do something like:

public static SaveUserStatuses Save(User user)
{
   SaveUserStatuses status = SaveUserStatuses.OK;


   if (!CheckIfBankAccountExists(user.BankAccount))
      status = (status | SaveUserStatuses.BankAccountMissing) & ~SaveUserStatuses.OK;

   if (!CheckEmailFormat(user.Email))
      status = (status | SaveUserStatuses.WrongEmailFormat) & ~SaveUserStatuses.OK;


   // you get the idea...

   if (status == SaveUserStatuses.OK)
   {
      if (!UsersDal.Save(user))
      {
         status = SaveUserStatuses.SaveFailed;
      }
   }

   return status;
}


The trick here is for every bad validation you add ("|" - bitwise OR)  the required status and remove the "OK" status by using "~" complement operator.

3). Finally, in our GUI:

SaveUserStatuses status = UserBL.Save(someUser);

if ( (status & SaveUserStatuses.BankAccountMissing) == SaveUserStatuses.BankAccountMissing &&
     (status & SaveUserStatuses.WrongEmailFormat) == SaveUserStatuses.WrongEmailFormat )
{
    // show the required message - client\user oriented !
}
// like the above - parse the status and show the required client oriented message(s).


This code smells a lot better:

a). We have no problem extending this code: (1) Add another member to the Enum (2) Add another check to our BL (3) handle the new status at GUI level.

b). We don't have to parse strings in order to build our errors. Parsing strings is error prone. Using Enum values can set a contract between the BL and the GUI. If someone will break it, we'll get compile time error (fail fast).

Back to code...

.NET | Design
Posted by Oren Ellenbogen 
06/04/2006 04:58, Israel time UTC+03:00,     Comments [5]  | 
# Friday, March 24, 2006

" Today, a real experience is much more important than a degree, well, unless you're looking for a government position. The problem in our industry is that students decide to study for the degree on the way, while trying to work in 120% job. In my opinion, if you want to give a student a chance at the real world while he can stay focus on his degree (and event enjoy it) you must assist him by finding him a position as an intern for at least a few months so later on he could apply to any position he'll be suited for. "

Well, that quote was mine(during launch time at my company). I'm one of those folks who tries to get my degree while trying to work my ass of. Sadly, I suffer 80% of the time as I struggle finish my papers for the universty on time and still enjoying my job(100% of joy). 
If internship was a part of the degree, I believe that the a lot of us programmers out there could enjoy the learning process without damaging our career and hack, maybe it will produce better programmers in our industry. 

In the USA (and in France too, as my cousin told me), this dream is a plain reality - you can see the internship project Joel Spolsky started here.

Posted by Oren Ellenbogen 
24/03/2006 10:02, Israel time UTC+02:00,     Comments [0]  | 
# Wednesday, March 01, 2006

I've fixed some wrong methods signatures in my article (thanks Ken) and uploded a demo which, I hope, ease the understanding of the entire article.

Go ahead and download.

Posted by Oren Ellenbogen 
01/03/2006 09:55, Israel time UTC+02:00,     Comments [0]  | 
# Monday, February 20, 2006

You remember my last post about templating via .Net 2.0 Generics and delegates. Well, after getting some good feedback from all of you, I thought to publish it at codeproject so I'll get some more feedbacks, grades and most important - additional comments.

Feel free to grade the article ;-)

 

Posted by Oren Ellenbogen 
20/02/2006 10:36, Israel time UTC+02:00,     Comments [2]  | 

For all of you programmers out there, who develop for asp.net 1.1 and asp.net 2.0 on the same machine - this trick can be quite useful for you !

If you're still using IIS, you'll want to create a VD(Virtual Directory) which support asp.net 2.0 for those application developed for that version, and still use VD which support asp.net 1.1 for your older application. Running an asp.net 2.0 application with VD of 1.1 (and vice versa, of course) will not work.
Where's the catch you may ask ?
Well, if you add a new virtual directory, you may notice that the chosen (default) version is the one you have in the Default Web Site. This can cause some annoying problems as some of your developers(or your server(s) administrator(s)) will define asp.net 2.0 as their default while the others will define asp.net 1.1 as their default. Just mentioning "define a new Virtual Directory for the application X" won't be enough.

The trick is to create a new Virtual Directory in the old fashion way, and just after it - call

%windir%\Microsoft.Net\Framework\[wanted version]\aspnet_regiis.exe -s w3svc/1/root [your Vitual directory name]

But hack, why do you need to remember all of this ?

Use the new(here is the old, without asp.net 2.0 support), improved, stylish, with asp.net 2.0 support - VDCreator:

VDCreator bin(EXE & Config only) (4.81 KB)

VDCreator Source (39.56 KB)


last but not least 
-
Ken helped me on this one so thanks mate !

Posted by Oren Ellenbogen 
20/02/2006 11:30, Israel time UTC+02:00,     Comments [0]  | 
# Thursday, February 16, 2006

It took me some time to understand the real power behind .Net 2.0 Generics. I think that the lack of usage with delegates hold me back from developing some elegant template-based code. After practicing a little, I managed to pull something off and I thought to share it with you. My goal - create a template for executing an IDbCommand object as a Reader, NonQuery, Scalar etc...
Posted by Oren Ellenbogen 
16/02/2006 10:16, Israel time UTC+02:00,     Comments [7]  | 

I wasn't aware of it, until now anyway...       

using (SqlConnection conn = new SqlConnection("your-connection-string"))
{
   string query = "SELECT * FROM T1; SELECT * FROM T2;";
   SqlCommand cmd = new SqlCommand(query, conn);
   
   conn.Open();
   SqlDataReader reader = cmd.ExecuteReader();
   do
   {
      while(reader.Read())
      {
         // read each row in the statement results.
      }
   }
   while(reader.NextResult()); // jump to the next statement results.
}

Posted by Oren Ellenbogen 
16/02/2006 08:21, Israel time UTC+02:00,     Comments [1]  | 

Level:

3/10 at Ellenbogen's scale.

Preface:

You have the following code:

try
{
   // Some code which can throw any kind of exception
}
catch(Exception e)
{
   // If e is from DataGatewayException type – throw the original exception;
   // Otherwise, wrap the exception with DataGatewayException and throw it.
   // In any case - this "block" will throw only DataGatewayException.
   if (!(e is DataGatewayException))
      throw WrapAndPublishException(e); // *
   else
      throw;
}


* WrapAndPublishException method returns a new object from DataGatewayException type (which wraps the original exception).

The Challenge:

Refactor the code above so it will be more readable and extendable(in case we want to re-throw other exception types as well).
Use your imagination.

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