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, 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", "    ");
   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+02:00,     Comments [0]  | 

I've just upgraded my CodeSmith version to 3.2; It went pretty well just until I've opened the CodeSmith Studio and tried to compile my template. I got a strange NullReferenceException in the CodeSmith.Engine.CodeTemplate constructor.
I thought about 2 reasons which can cause this behavior:

  1. Maybe the CodeSmith Studio works with an old version of one of the dlls, for some unknown reason (unlikely).
  2. I'm using a compiled dll as my CodeTemplate base class, maybe I need to recompile it again and then try to compile the template (more likely).

So I compiled my DLL (and did a quick restart to my computer, just to be safe) - now it works...

Posted by Oren Ellenbogen 
01/02/2006 10:25, Israel time UTC+02:00,     Comments [0]  | 
# Saturday, January 28, 2006

After a long meeting with Ken and Roee about our(SQLink R&D department) architecture, I decided to put it out on the table - maybe you can give us some better insights about some questions we brought up during our session. I'll start from the end of our session - this is the architecture design we thought about:

layers_small.jpg

Posted by Oren Ellenbogen 
28/01/2006 03:22, Israel time UTC+02:00,     Comments [4]  | 

I'm using the Captcha anti-comment-spamming-engine in my blog:

captcha.jpg

Some of you complained that after posting a comment you can't see it afterwards. This is caused due to a time mechanism plugged in the Captcha engine - after X seconds, the code becomes invalid and you have to insert a new one. In case that the Captcha will have code timeout - it will make you enter a new generated code simply by leaving you on the same page. So please make sure that after hitting the "Save Comment" you're on the main page and you don't have your comment at the bottom of the page, if so - enter the new code and click the "Save Comment".

Thanks.

Posted by Oren Ellenbogen 
28/01/2006 02:04, Israel time UTC+02:00,     Comments [1]  | 
# Friday, January 27, 2006

After elaborating on the topic on my first post (see comments), it's time to wrap the all thing up. As I've noted, the purpose was to brought up some points of interest about developing classes which wrap unmanaged code inside them. When I'm reviewing my teammates code, any usage of unmanaged code triggers me as I start thinking about all the scenarios of which the unmanaged code stays un-handled and therefore causes memory leaks in the application. One of the scenarios which can cause a memory leak was the one we've talked about(again, the code in the first post was only for teaching purpose, so this post will be more relevant), but this could be better handled by implementing "Dispose pattern" on the (wrapper)class.
Posted by Oren Ellenbogen 
27/01/2006 01:33, Israel time UTC+02:00,     Comments [1]  | 
# Tuesday, January 24, 2006

Consider the following code:

* Note: this code was written for teaching purpose only and is highly not recommended in "real world" implementation.

public class CustomWriter : IDisposable
{
   private StreamWriter m_sw;

   public CustomWriter(string filePath, int numberOfLinesToWrite)
   {
      m_sw = new StreamWriter(filePath);

      if (numberOfLinesToWrite < 0)
      {
         throw new ArgumentException("What's wrong with you ?!!? numberOfLinesToWrite can't be less than 0", "numberOfLinesToWrite");
      }

      // Assume that I'm using numberOfLinesToWrite here...
   }

   #region IDisposable Members

   public void Dispose()
   {
      // Time to say goodbye
      m_sw.Close();
   }

   #endregion
}

And now, here is a simple runner:

using (CustomWriter cw = new CustomWriter(@"c:\oren.txt", 15))
{
   // some code here...
}

This one works as expected and the StreamWriter is being cleaned as using calls the Dispose method.

But what happens if the path is invalid like "c:oren.txt" or maybe "c:\windows\system32\cdosys.dll" ??
Nothing much to tell the truth as the resource(StreamWriter) will die and fail to initalize - we're OK.

But what about this scenario:

using (CustomWriter cw = new CustomWriter(@"c:\oren.txt", -5)) // <-- Remember? "-5" is invalid argument
{
   // some code here...
}

Now we're in trouble: The Dispose method is NOT called at all and the resource is running free on the memory street with no GC(garbage collector) police to hold him back (a little metaphor, why not?). Need I to say how BAD this case is ?!

 

To sum it all up: constructors should NEVER throw any kind of exception. If you have a case which you need to do some extra initialization that could throw an exception in certain cases - do it in a method inside the class (Initialize() sounds right).

* I'd like to give the deserved credit for Amir Engel(His blog is on its way, hold tight) for elaborating on the subject with me ;-)

Posted by Oren Ellenbogen 
24/01/2006 05:14, Israel time UTC+02:00,     Comments [8]  | 
# Monday, January 23, 2006

A dear friend of mine, Shani, wrote a great post about the subject which I highly recommand; Pay him a visit.

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

I've written a method which will format any given string into a more readable phrase. This method can be quite useful if you're generating your code or building your API based on an outer settings like a config file, DB, Reflection etc. Here is the code...
Posted by Oren Ellenbogen 
23/01/2006 06:49, Israel time UTC+02:00,     Comments [0]  | 
# Sunday, January 22, 2006

must read, IMO, article about xml parsing:

http://support.softartisans.com/kbview.aspx?ID=673

This will give you some insights about the options available for you via .Net framework for parsing\manipulating xml data.

Posted by Oren Ellenbogen 
22/01/2006 07:46, Israel time UTC+02:00,     Comments [1]  | 

This post is mostly a self reminder but it may come useful if you're using CodeSmith as well.
It is possible to check if a (schema)column is an identity field via ExtendedProperties property of the SchemaObjectBase class:

// Only for Sql Server
private bool IsIdentityColumn(ColumnSchema column)
{
   return (bool)column.ExtendedProperties["CS_IsIdentity"].Value;
}

There is one exception though and that's if you're sending the column object through the TableSchema.ForeignKey[index].ForeignKeyMemberColumns or TableSchema.ForeignKeys[index].PrimaryKeyMemberColumns, meaning:

for(int i=0; i<MySourceTable.ForeignKeys.Count; i++)
{
   // Same thing about MySourceTable.ForeignKeys[i].PrimaryKeyMemberColumns...
   for (int j=0; j<MySourceTable.ForeignKeys[i].ForeignKeyMemberColumns.Count; j++)
   {
      if (IsIdentityColumn(MySourceTable.ForeignKeys[i].ForeignKeyMemberColumns[j])) // <-- Exception Here.
      {
         //do some code
         
      }
   }   
}

The extended properties will NOT hold the key "CS_IsIdentity" and IsIdentityColumn will throw an exception (null reference). I'm still not sure if this is by design or not, so I'll try to fish it out on from the net and update the post later on. 

The solution is simply working a little harder via TableSchema.Keys and than verify the type of the key (by PrimaryKeyTable and ForeignKeyTable properties).

update:
This is quite a dirty hack, but it works and I'm loving it (I don't have to change a lot of code in a lot of different places) !  
I refactor the mehotd IsIdentityColumn so it will do the trick:

private bool IsIdentityColumn(ColumnSchema column)
{
   if (column.ExtendedProperties["CS_IsIdentity"] == null)
      column = column.Table.Columns[column.Name];

   return (bool)column.ExtendedProperties["CS_IsIdentity"].Value;
}

Back to code...

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