# 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-07: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-07: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-07: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-07: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-07: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-07: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-07: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-07: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-07: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-07:00,     Comments [5]  | 
# Tuesday, February 07, 2006

For some strange reason, I can't seem to debug my .Net 2.0 application via VS.NET 2005 debugger. I call Debug.Fail("...") in my code and run it via Ctrl+F5 - this is the screen I get:

no2005debugger.jpg

Where the hack is my VS.NET 2005 debugger ?!
If anyone found my lost debugger, please send it back to this address (via comment).

Thanks!

btw - debugging with F5 works fine; That makes me wonder how can I control the items in the box (at the picture), maybe registry magic is required. I'll update if I'll manage to find my debugger ...

 

   

Posted by Oren Ellenbogen 
07/02/2006 12:21, Israel time UTC-07:00,     Comments [2]  | 
# Monday, February 06, 2006

I'm trying to give some good PR to the Israeli MCPD study group, arranged by Justin Angel (Hebrew).
So if Hebrew is native for you and you'd like to hear some good(hopefully) presentations about .Net 2.0 - leave a comment in this post. It's important to get some early feedback as Justin tries to get a classroom (& some food) from Microsoft so they'll  sponsor the event.

See you there...

   

Posted by Oren Ellenbogen 
06/02/2006 02:00, Israel time UTC-07:00,     Comments [0]  | 
# Sunday, February 05, 2006

I just found a bug in the new version of SchemaExplorer (3.2.4.797) at MemberColumnSchemaCollection.Contains(CoolumnSchema value) method.
   

Posted by Oren Ellenbogen 
05/02/2006 02:25, Israel time UTC-07:00,     Comments [1]  | 
# Saturday, February 04, 2006

Roy did a great interview with Kent Beck, an author of several books about XP\Agile development and one of the most influence figures in that industry. I tried to think about the answers I would give Roy if he asked me some of those question, so here are my answers and some short feedback about the interview itself:

Push yourself to your extreme.
I'm one of the folks Roy mentioned that tries to get better by testing new methodologies\practices like Pair Programming, Unit-Test-first code-after, daily build process (etc) when I have the chance of doing so. By saying that some of the techniques such as Pair Programming just couldn't work here in Israel due to our complex nature(intolerance and straight-hard-to-your-face-comments) is somewhat rude (see - I'm a good Israeli, no problem saying "hard comments" ;-)) as the term "Pair Programming", IMHO anyway, doesn't necessarily mean working on the same code at the same time; It's about thinking and discussing about the same context and move toward the solution at the same time - something which I enjoy doing on my every day work and I'm familiar with many more programmers out there that practice this technique in their every day work.
I think that Kent gave a good answer: those methods DO work(even in Israel) - the context or definition of "success" is debatable and can go either way, but those methods serve a better all as our main goal is to be the best we can be, and XP\Agile techniques are just some more tools and ideas for us to become so. That attitude, the "extreme achiever-wannabe", is the one I'm searching of at people, and this is what I'm working hard on in order to inspire others.
 
The cold hard truth - one man can't(?) change an entire organization.
Every once in a while I hear(while someone just throws it at my face) the sentence "you're still young and naive, you can't change this\that\him\her" or "you've been lucky to work with those people; with my teammates you couldn't done it..."; I guess that I'm just one of those optimistic people which think that by doing your best and influence others by your positive nature will work (to some extent, as I mentioned earlier) in any given group of people unless this group is doomed for failure and are willingly accept it. Can one man can change the world? I guess not, but I would like keep thinking so as I know that this will give me the inspiration and motivation I need. The definition of success is bound to the "ribbon" you're attached to. As a programmer, your world is pretty small but you can definitely make it spin in the reverse direction if you push hard enough. It would be much more difficult to change the world of other team in your department, I just think that this shouldn't stop you.
 
"People want some hard answers which will inspire them to get better"
Roy - I can't agree more, and at the same breath, I can't disagree more on this phrase. You see, most of us want hard answers as we wish to believe that by applying other methodologies\actions\thoughts we're improving our-selfs and raising our bar just one inch higher in the path of becoming better; So I definitely think that hard answers for complicated question, in some of the cases(case = person&context), will create the wanted effect.
On the other hand, the more creative you are, the more "self-succeeder" you want to become - the less it will apply to you. Meaning, I don't want to get straight answers about "What is the right way to develop a 6 months project with 3 programmers and one team leader" and the reason is simple - any answer you'll give will be wrong, but at the same time it will be also right so I'm still at step one. As you get older you realize that there is no right answer, so reading a book, or asking Kent for his opinion is just another (great)source\idea\tool to add to you tool-box, nothing more. Showing your attentions and discuss about those hard questions with other co-workers can cause the required inspiration that people are so eagerly searching for.
 
General feedback:
Roy - I think that you did a great job "pinning" Kent to the corner and ask the really hard questions about XP\Agile development which can seem like empty buzzwords instead of real solutions to specific organization\projects\teams\context in the eye of the intermediate programmer. I can't say that I've learned something entirely new, but It sure made feel better about my grasp of software development and people management.
Kudos for your not-so-Israeli accent(:-)) and for your time !
   

Posted by Oren Ellenbogen 
04/02/2006 02:19, Israel time UTC-07:00,     Comments [1]  | 
# Wednesday, February 01, 2006

I'm using dasBlog "Insert Code" feature in order to insert some code to the post(strange, but true). Until now, my code was nicely highlighted but it was lacking of background color and some border to give it the proper attention it was required. After digging for couple of seconds in the dasBlog directory I found out that the page ftb.insertcode.aspx (under ftb directory) is in charge of highlighting the code. Here are the important lines (Notice the background color & border ! :-)):

void parseButton_Click(object sender, EventArgs e)
{
   AylarSolutions.Highlight.Highlighter h = new AylarSolutions.Highlight.Highlighter();
   h.ConfigurationFile = Server.MapPath("CodeHighlightDefinitions.xml");
   h.OutputType = AylarSolutions.Highlight.OutputType.Html;
   string result = h.Highlight(sourceTextBox.Text, languageDropDown.SelectedValue);
   result = result.Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
   result = result.Replace(Environment.NewLine, "<br>");
   resultLabel.Text = result;
   codeText.Text = "<p>" + result + "</p>";
}

All you have to do is replace the line:

codeText.Text = "<p>" + result + "</p>";

With this:

codeText.Text = "<p class='HighlightedCode'>" + result + "</p>";

Now add the class into your template css and that's it!

* I'm using:

.HighlightedCode
{
    border-style: dashed;
    border: 1px Silver;
    background-color: White;
    margin-left: 10px;
    margin-right: 10px;
    margin-bottom: 10px;
    margin-top: 10px;
    padding-left: 4px;
    padding-right: 4px;
    padding-bottom: 4px;
    padding-top: 4px;
}

Sweeeeet !
   

Posted by Oren Ellenbogen 
01/02/2006 05:18, Israel time UTC-07:00,     Comments [0]  |