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.
# Wednesday, September 20, 2006

<rational thinking>

Let's assume we have a WebSite(the same issue applied to WebService btw) named WebApplication1. Now, we want to put its(the website's) output files into some other directory (!= "bin" directory) for development reasons (working as part of a team with some sophisticated Source Safe). What's the first thing you (and me) do? we use our "rational" programmer nature and Right-Click on the project->Properties->Build Tab->and changing the Output path to whatever we need.

OutputPath.gif

(Instead of "bin\" we can write here "..\..\infrastructure" for example)


We then build the all thing and surprise surprise, the new output path contains all the dlls as expected. Awesome!
Satisfied with the greatness of Visual Studio .Net 2005, we now want to Publish the WebSite so we(or the QA) can play with it. "Think as a developer, think as a developer" I say to myself and Right-Click the WebSite project->Publish... A few really easy "decisions" and ~10 seconds later, VS.NET tells(it speaks to me, I swear) me that my site was published successfully.

Happy as a little girl with a new puppy, I enter my site: http://localhost/webapp1/Default.aspx and Oops!

OutputPathUnableToFindClass.gif

The page can't find its "code behind"(The class that it inherits from)! What the hack is going on here!?

Well, it turns out that the Publish process is not as smart as you may think it should be. Changing our Output path to another directory (!= "bin") caused this all mess as the Publish process simply copy all the files from the bin directory into the new(Published) bin directory. No questions asked. The Publish algorithm do not check if you actually compile your dlls into another directory via Output path and taking it into account.

</rational thinking>

<effective thinking>

Fortunately for us, the solution is pretty easy: define your Output path into the original location ("bin\") and use the Build Events(post-build in this scenario) in order to copy the output files into your "infrastructure"(or whatever) directory like this:

OutputPathUsePostBuild.gif

(The command: xcopy /Y /S ${TargetDir}*.* ..\..\Infrastructure)

</effective thinking>


May it save you the 15 minutes it took me and my teammate Hagay to solve this one.

Posted by Oren Ellenbogen 
20/09/2006 04:12, Israel time UTC+03:00,     Comments [2]  | 
# Sunday, September 17, 2006

The solution is pretty simple, just add the support(in bold) for the httpPost protocol in your web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <system.web>
       <webServices>  
        <protocols>   
            <add name="HttpPost"/>  
        </protocols> 
       </webServices>
    </system.web>
</configuration>

Publishing the WebService do not automatically add these lines so you'll have to do it manually.

Posted by Oren Ellenbogen 
17/09/2006 11:43, Israel time UTC+03:00,     Comments [0]  | 
# Tuesday, September 12, 2006

I've just opened Yediot Acharnot's(one of the largest newspaper in Israel) site - Ynet.co.il:

newspaper.gif

On the bottom-left of the picture you can see the title "The Palestinians: 13 years old was killed by the Israeli Defense Force fire". Reading a few sentences inside of the article paints a different picture: several Palestinians terrorists, and the 13 years old boy among them, throw a grenade on our soldiers and one of our officers was hit. The fire was in response to that grenade. What the hack a 13 years old boy running with terrorists? Should we not defend ourself? Would you remain motionlessly after being hit by a grenade!? I doubt it... This boy have a mother and father, where were they? The hatred made them blind? made them believe that their son's life are not worthy? Is it OK to send your son to explode and than raise his little brother to follow his path?!

The Lebanon War was exactly the same - they(Hizbala) fired missiles from civilians houses and then entered the building. Did our army react? in 99.9% of the time the answer was NO(you didn't hear about it right?); One time (Kfar Kana) we did react - the entire world was shocked by it for several days. Where are the pictures of the destroyed houses by that missile? Where are the Israelis Pictures who died from that missile? 

Did Kadafi asked himself why a terrorist entered a building after firing a missile? I bet that he did. "Well, they fight the way they fight. I don't find logic in their actions that I can relate to, but it must be there... right?".

Did you ever see on television(CNN, FOX news, whatever) a 13 years old kid throwing a grenade on a tank that kills our soldiers or the 5 minutes later that this kid was shot? Why don't you investigate where his parents were at that time? What about the terrorist that threw a grenade inside a house with civilians in attempt to kill one of our soldiers and "accidentally" killed the civilians in that house? I guess you heard something like "Israeli Defense Force killed an entire family while catching a terrorist". What about the 100->55->44->30->22 dead in Kfar Kana. The German's press(no the Israeli press, the German's!) took picture of the place and they catched(on video) that the bodies were moved around just so it will appear that more than 100 people died!

That's OK, I don't expect from the outsiders to play nice, to cover all the facts and tell the story from our side as well(I'm no journalist, but isn't it the first rule you learn - "cover the story from every angle"). That's asking too much I assume. But from Israeli media I do expect more! These reporters make us look bad. Tell the story as it was and emphasize the cause that lead to that result, you are Israeli reports for god sake!!

The funny stuff is that we(the Israelis) always think that our ambassadors are not doing it(Public Relations) right on the outside.
We are so wrong. Our problem is from the inside, if a guy like me have to read this story from the Palestinians side and in small letters - our side, in an Israeli newspaper, it's our fault.

Shame.

I really tried not to get into the core of my thoughts as it might start a World War III which is usually a bad thing(right?). Our people want peace, we want to live with our neighbors, we do hurt that their kids are dying and our people are being bumbed in buses. I sometimes wonder though, what about the other side? What about the world?...

Posted by Oren Ellenbogen 
12/09/2006 08:43, Israel time UTC+03:00,     Comments [0]  | 

In our migration process, we encounter a few(~6) VB6 classes with heavy logic in their destructors. In the old world of VB6, the destructor was called after setting the object to Nothing (deterministic destructor) which is quite the opposite than the new world of .Net where the Garbage Collector is in charge of disposing the objects and you can't never know when the destructor will be called. This means that wrapping an old VB6 dll with an Interop and using one of it's classes in our .Net classes, will now make its destructors non-deterministic(The proxy is also managed in the CLR, so it behaves by the same rules every .Net class follow) which is very bad for our application - performance-wise, memory leaks etc. Our solution was to force the disposal of the object by calling Marshal.ReleaseComObject in a "Interop Wrapper", and here is the concept:

Let's say that we have a VB6 dll named Class1.dll (COM dll) which contains MyService class with some logic in its destructor.
We create an Interop for it which will be called Interop.Class1.dll (this is .Net assembly).
And here is our "Interop Wrapper" (named ComObjectScope) and our consumer(MyClass).

/// <summary>
/// Wrap a COM object in order to control its life cycle (deterministic disposal).
///
/// Usage:
/// MyComObject obj = new MyComObject();
/// using (new ComObjectScope(obj))
/// {
/// // Use obj here.
/// } // here obj will be disposed. Don't use it outside of the using block.
/// </summary>
/// <example>
/// MyComObject obj = new MyComObject();
/// using (new ComObjectScope(obj))
/// {
/// // Use obj here.
/// } // here obj will be disposed. Don't use it outside of the using block.
/// </example>
public class ComObjectScope : IDisposable
{
   private bool _isDisposed = false;
   private object _comObject;

   public ComObjectScope(object comObject)
   {
      if (!comObject.GetType().IsCOMObject)
         throw new ArgumentException("The provided object must be of COM object type.");

      _comObject = comObject;
   }

   protected virtual void Dispose(bool disposing)
   {
      if (_isDisposed)
         return;

      if (!_isDisposed)
      {
         if (disposing)
         {
            Marshal.ReleaseComObject(_comObject); // This baby release the COM object for good.
            _comObject = null;
         }
      }

      this._isDisposed = true;
   }

   public void Dispose()
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }

   ~ComObjectScope()
   {
      Dispose(false);
   }
}


public class MyClass
{
    public void DoSomethingWithComObject()
    {
        Interop.Class1.MyService service = new Interop.Class1.MyService();
        using (new ComObjectScope(service))
        {
            // ...
            // use service here as needed.
            //....
        
        } // here service will die and its destructor will be called

        // don't use service here! you'll get NullReferenceException
    }    
}

.NET | COM
Posted by Oren Ellenbogen 
12/09/2006 07:30, Israel time UTC+03:00,     Comments [1]  | 

This post is mainly self referral, but hack - it might be useful for the random reader as well.

We are converting a few (very small)projects of us from VB.NET 2.0 into C# 2.0. We thought that converting everything manually will take something like 2 hours, but we managed to find an on-line convertor that will cut our work into ~10 minutes. The 10 minutes will be spent on building a new Project as this on-line tool can't migrate our *.vbproj files into *.csproj files. There are tools on the market that actually support it, but they cost money and therefore recommended only if you migrate big chunks of code\projects\solution.

Our migration process:

1. Create a new C# Project for each VB.NET Project.
2. Create classes files in C# for each VB.NET files.
3. Migrate each VB.NET code via the automatic tool and put the result in the related C# file.
4. Run our Unit Tests.
5. Delete our VB.NET projects (bye bye VB.NET)
6. Smile... :-)

You can find the automatic convertor tool here.

Posted by Oren Ellenbogen 
12/09/2006 03:28, Israel time UTC+03:00,     Comments [4]  | 
# Monday, September 11, 2006

Source Code:

RhinoMocksExample.zip (94.18 KB)

You will need to download and install Nunit 2.2.8 and RhinoMocks(for .Net 2.0) in order to run the tests.

Background:

Not as usual, we'll start with the code and continue with it's UnitTests.
We have a single, simple class named MailService. This class contains one method named MailText(string textToMail, params MailInfo[] mailList) that looks like this:

public class MailService
{
   private IMailValidator m_mailValidator;
   public IMailValidator MailValidator // setter, getter

   public void MailText(string textToMail, params MailInfo[] mailList)
   {
      foreach (MailInfo mail in mailList) { //I know I can collect addresses...
         ValidationResult validationResult = this.MailValidator.Validate(mail);

         if (!validationResult.IsValid)
            throw new ArgumentException("Invalid mail: " + validationResult.ValidationMessage, "mail");

         // Send the email somehow...
      }
   }
}

And here is the IMailValidator, MailInfo and ValidationResult:

public class MailInfo {
   public string Address; //not best practice
   public MailInfo(string address) { this.Address = address; }
}

public class ValidationResult {
   public bool IsValid; //not best practice
   public string ValidationMessage; //not best practice

   public ValidationResult() { IsValid = true; ValidationMessage = string.Empty; }

   public ValidationResult(bool isValid, string message) {
      IsValid = isValid;
      ValidationMessage = message;
   }
}

public interface IMailValidator {
   ValidationResult Validate(MailInfo mail);
}

That is pretty straightforward I hope.


Testing inner behavior:

MailService.MailText has one dependency to IMailValidator. One way of testing our MailService.MailText method is via manual stub implementation of IMailValidator. Let's examine the tests and then look at the manual stub I've created.

1). Manual stub based testing:

[TestFixture]
public class MailServiceTests
{
   [Test]
   public void MailText_OneValidEmail_MethodWorks()
   {
      MailService service = new MailService();
      MailInfo mail1 = new MailInfo("valid@mercury.com");

      service.MailValidator = new StubMailValidator();

      service.MailText("Enlarge your 'memory stick'", mail1);
   }

   [Test]
   [ExpectedException(typeof(ArgumentException))]
   public void MailText_OneValidEmailAndOneInvalidEmail_ThrowException()
   {
      MailService service = new MailService();
      MailInfo validMail = new MailInfo("valid@mercury.com");
      MailInfo invalidMail = new MailInfo("invalid.com");

      service.MailValidator = new StubMailValidator();

      service.MailText("Enlarge your 'memory stick'", validMail, invalidMail);
   }
}

And here is the simple StubMailValidator in one of it's versions: (This stub was developed after the first test(MailText_OneValidEmail_MethodWorks) was written)

public class StubMailValidator : IMailValidator
{
   public ValidationResult Validate(MailInfo mail)
   {
      ValidationResult res = new ValidationResult(); //default: valid.
      if (mail.Address.IndexOf(".com") == -1) {
         res.IsValid = false;
         res.ValidationMessage = "The email address must end with .com";
      }

      return res;
   }
}

NOTICE: Manual stubs with inner logic can be devastating !

As you may or may not notice, this stub has a bug in it. Just look at the second test on the "invalid.com" MailInfo. This is an invalid email address and yet, our stub will say that it's valid and fail our second test. This is extremely dangerous! It is one of the things that makes people afraid from Unit Testing. When your stub need to switch his response according to a given parameter(s) based on some logic, you better switch your manual stub with dynamic\generated stub. You don't want any test-related logic outside of your test method. Let's look at mocked stub testing.

2). Mock stub based testing:

I'm using Oren Eini's (aka Ayende) RhinoMocks for simulating "controlled" implementation of IMailValidator. That means that you are creating some dynamic implementation of IMailValidtor and you are telling it how to act when the tested method calls it.

Let's look at our first test:

[Test]
public void MailText_OneValidEmail_MethodWorks()
{
   MailInfo validMail = new MailInfo("valid@mercury.com");
   ValidationResult validValidationResult = ValidationResult(true, string.Empty);

   // ------ (1) -------
   MockRepository mocks = new MockRepository();
   IMailValidator validator = (IMailValidator)mocks.CreateMock<IMailValidator>();
   Expect.Call(validator.Validate(validMail)).Return(validValidationResult);
   // ------------------

   service.MailValidator = validator;

   mocks.ReplayAll(); // Make sure the mock object is ready to "respond"

   service.MailText("Enlarge your 'memory stick'", validMail);

   mocks.VerifyAll(); // Make sure everything was called correctly.
}

(1) - This is the important stuff. I'm asking the MockRepository to create a new Mock from IMailValidtor type that our MailService expect. The line in bold tells this story: "listen dear mocked validator, if someone calls your Validate method with the parameter validMail - please send him back validValidationResult object". If we know that our validator will be called twice - we'll have two lines with Expect.Call as needed.

One of our main purpose in UnitTesting is to test one method (and one method only) and see if it behaves correctly if it receive a certain data. We also want to check the stomach of the method, what happen if our tested method calls another method(dependency) that return "1" - will it still behave as expected? Via Mock object I can control the dependency object's result easily inside the test. This make it very easy to detect bugs in contrast to our manual stub that sits somewhere else, outside of our test.

Recap:

If you have a dependency to some other object and your manual stub start to contain logic, you should mock that dependency and control the returned values in the same place you write your tests via mock object.

Bonus (delegates style Interaction Based Testing):

[Test]
public void MailText_OneValidEmail_MethodWorks2()
{
   MailInfo validMail = new MailInfo("valid@mercury.com");
   ValidationResult validValidationResult = ValidationResult(true, string.Empty);

   RunMock<IMailValidator>(
      delegate(IMailValidator validator, MockRepository repository) {
         Expect.Call(validator.Validate(validMail)).Return(validValidationResult);

         service.MailValidator = validator;
         repository.ReplayAll();

         service.MailText("Enlarge your 'memory stick'", validMail);
      }
   );
}

private void RunMock<TObjectToMock>(MockedProc<TObjectToMock> func)
{
   MockRepository mocks = new MockRepository();
   TObjectToMock obj = (TObjectToMock)mocks.CreateMock<TObjectToMock>();

   func(obj, mocks);

   mocks.VerifyAll();
}

private delegate void MockedProc<TObjectToMock>(TObjectToMock mockedObject, MockRepository repository);


Enjoy!
.NET | TDD
Posted by Oren Ellenbogen 
11/09/2006 11:30, Israel time UTC+03:00,     Comments [1]  | 

We are writing .Net classes that will have to be used by COM objects. Therefore, we had to mark our objects with GuidAttribute and implement an interface that match every method we want to expose. In VB.NET Project, there is a COM Class which my colleague friend, Doron really like and is missing in C# Project. I decided to make a "C# COM Class" template so here you go:

C# Com Class.zip (7.92 KB)

Install:
Put the zip(don't extract it!) in: %USERPROFILE%\My Documents\Visual Studio 2005\Templates\ItemTemplates\

Usage:

1). Open a new instance of VS.NET 2005 and create a new C# Class Library Project.
2). Right-Click on the project -> Add -> New Item...
3). Select C# COM Class.

csharpcomclass.gif

4). Now insert a name, let's say: MyClass.

csharpcomclass_example.gif

* The namespace will be auto' generated by the project's default namespace.

Enjoy.

Posted by Oren Ellenbogen 
11/09/2006 05:02, Israel time UTC+03:00,     Comments [1]  | 
# Friday, September 08, 2006

"Inline Search is an extremely useful free add-on for Internet Explorer that mimicks Firefox's search behavior i.e. it turns searching into a web page into a non modal research experience coupled with a search as you type facility. It integrates flawlessly into IE (version 5.5 or above), giving it that little extra that makes you a lot more efficient when you are looking for a specific piece of information." (via Core Services)

This add-on is fantastic !

You can download it here.

Posted by Oren Ellenbogen 
08/09/2006 01:19, Israel time UTC+03:00,     Comments [3]  | 
# Thursday, September 07, 2006

I can't think about a better phrase to describe the latest songs in the industry. Listening to the radio makes you switch between the stations like you have some kind of disease; The songs lost all their meanings and instead we are swamped with "catchy" songs that we hate, but just can't live without whistle them every 2 minutes or so. Just listen to Justin Timberalke's latest song - "SexyBack", this is all about the catchy music, the words are completely irrelevant and you can't even hear the singer as the drums block his(?) voice(I'm not sure it's even Justin's voice). Does Justin OK with this kind of music? I'm not sure, but I *hope so. It still makes me think a lot about the way I worked until now and the way I'm working today; I really believe that being a programmer is as artistic as being a singer or a writer. There were times in life that I felt we are writing code just to make half-baked applications and ship them out to the mass(our clients), the quality was peripheral, and it conflicted with my "artistic"-self values. Are you familiar with that feeling ? There were also times of elation, when our code was beautiful, pure, magical. It made me smile talking about it later on. Working on a big product, at Mercury, and talking with the (amazing)guys at work, made me feel how lucky I am. Thankfully, I'm still in a position in life that I can made an influence, although I'm not naive and fully aware to the fact that clients are always right and $$$ will dictate deadlines and features packs. There is one sentence I keep saying to the guys working with me (since I was 16) - "be proud of your code". Write your name in big, CAPITAL LETTERS, at the beginning of your files, make sure everyone knows YOU did it. This will push you into excellence (you don't want others looking in your code and swearing your mom, do you? update: your mom says "no!") and inspire you to think about better, more creative and unique solutions instead of ad-hoc, ugly "But hey, it works!" solutions.

So, please, don't let **marketing or money dictate your life. Everything in Life is a trade-off, but you should decide your path, don't walk silently in a path carved by others even if it's easier. At the end of the day, saying "But I had to" or "But it's shorter" will not make you sleep better at night; If you like what you're doing, I'm sure that you are familiar with the feeling.


* I know. he is rich & famous, he must be happy. Does he ? maybe...
** Unless this is your decision, which makes it OK. As long as it is your choice.

Posted by Oren Ellenbogen 
07/09/2006 08:31, Israel time UTC+03:00,     Comments [1]  | 
# Friday, September 01, 2006

A few months ago, I lectured before Microsoft C#/C++ User Group about advance usage of delegates, generics and anonymous methods. The audience was great and I got really nice feedback. I was talking with my good friend Pavel a few days ago about lecturing in general and he made an excellent point: I should have done more "rounds" with this lecture. This could have been good experience for me to learn from the feedback I got and use it into practice before different audience. So, would you like to hear me present for ~1.5 hours about those topics (after "work hours", say 17:30+) in your "home"(=working place)? All I need is a projector and a working air conditioner(I don't have 3 built-in fan as my computer have, unfortunately). You can look at the lecture syllabus here and there are code samples and presentation(ppt) file of the entire thing right here. Of course, there should be a minimum number of people attending as I don't want to drive for an hour just to talk with 2 people (actually, I do, but this won't be very productive and bad usage of my time, so I'm sorry folks).

Minimum knowledge required to participate: good understanding of .Net 1.1 is a must; .Net 2.0 - bonus.
Lecture ("MS")Level: 400. (technical hardcore stuff, no SOA will be presented, I promise).


Drop a comment or send me an email (oren dot ellenbogen at gmail dot com) and we'll set a date.

Posted by Oren Ellenbogen 
01/09/2006 12:44, Israel time UTC+03:00,     Comments [0]  |