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.
# Saturday, June 10, 2006

I'm doing some thinking about our GUI, Data Access Layer, Entities and the way we should combine them. Looking a little further, LINQ is just a matter of time and effort until we'll use this great infrastructure. I've downloaded a few movies about LINQ from Channel 9, and started to glance at my future. If you're an architect, you should really take a look at Chatting about LINQ and ADO.NET Entities. This will give you a better insight about LINQ's Architecture and where you should intervene if needed.

Our department uses a product we developed in-house named Code-Agent which allows us to generate our application based on our ERD. At current stage, we have our own infrastructure for manipulating data between our tiers, but it lacks some abilities which I really want to see in the near future.

This movie made me *think*.

But before I'll carry on with my insights, let me talk about LINQ, IQueryable<T> and lamda expressions; Let's start with a little example:

var results = from order in orders
              where order.Amount > 100
              select order.Name;

results will now contain all the orders with amount > 100.
The CLR transforms this query into method calls:

var results = orders.
                  Where(delegate(Order order) { return order.Amount>100; }).
                  Select(delegate(Order order) { return order.Name; });

Or via Lamda expression (kind of version 2 to anonymous method):

var results = orders.
               Where(order => order.Amount>100).
               Select(order => order.Name);

Seeing this kind of solution immediately made me think about writing our own LINQ wrapper for the meanwhile. Still, I can't work on production code with LINQ as it really premature at current build but I can definitely build some sort of engine which implement the core principles of LINQ and in time remove my implementation, bit after bit. The next step was to look for IQueryable<T>, this baby inherit from IEnumerable<T> and let you do this magic I've demonstrated above (Where, Select, Group By, Order... you name it). I found a great post on this matter at Wayward Blog.

What's the next step you might ask ?
I guess the answer is to emulate IQueryable<T> in our current infrastructure and aim for compatibility and consistency with LINQ.

Here is a quick implementation which pops out of my head:

EntityCollection<Order> orders = 
                  EntityCollection<Order>.
                     Where(delegate(Order o) { return o.Amount > 100; }).
                     Select(delegate(Order o) { return new { o.Name, o.Id }; });

foreach (Order o in orders)
{
    Console.WriteLine("Order id: " + o.Id + " name: " + o.Name);
}

EntityCollection<T> will inherit from IQueryable<T> and implement the basics.

It's time to get into code-till-I'll-bleed mode...

.NET | Design
Posted by Oren Ellenbogen 
10/06/2006 05:09, Israel time UTC+03:00,     Comments [0]  | 
# Tuesday, June 06, 2006

Reading Oren Eini's post & comments about How to tell that this is not production code made me nervous. I don't know why but for 10 long-enough seconds my eyes twinkled and I managed to pull 5 buttons from my keyboard.

Due to the fact that I know Oren's character from talking to him quite a bit after my lecture(delegates&anonymous mothods), I have the feeling that he codes-for-fun instead of coding-to-succeed, and he really pushes it sometimes. I can't say that I'm no sinner, but I think that during working hours, you should use your team's time in a wiser manner.

You should code with purpose. This purpose should be with one stand to your project deadlines, people quality, maintainability, efficiency, company's goals etc. This is code-to-succeed in my book.

I wrote this comment down as I'm currently responsible for several applications with some code that actually made me think that this code which "should never be production" made its way into production. It's even worse, the knowledge of how and why this code behaves the way it does is *lost*. The people who wrote it are no longer here and I'm stuck with code that shouldn't exists. Oh yes, I almost forgot, this code has numerous bugs and yep, I will have to play along with this dark magic voodoo and get it to work.

One sentence (from Eini's comments) really got me anemic for couple of seconds:
"We are going to try to explain it tomorrow to another developer, who is going to maintain it, and we will see if he likes it or not."

This is *unacceptable*. You know that you're doing some dark magic, you know that this is a disaster waiting to happen and yet you move forward. Let's say that this poor fellow got the idea, what happens if he quit and a new programmer will have to take care of *your* code ? Who says that you'll be there to hold his hand ? Who says that he will "like" it ? You must know when to stop...


Wait a minute, hold on, you got me all wrong here !

I'm all about creativity and enthusiasm(!!!!), especially during work time, but the above is just a bad practice and not an excuse. Does that mean you can't code things you know you'll have to change later on or even throw them to the garbage ??
Hell no ! this is exactly why you can prototype your solutions if required. Just don't forget to throw the prototype to the garbage and start all over again with the good insights you have acquired during the process.

Posted by Oren Ellenbogen 
06/06/2006 01:49, Israel time UTC+03:00,     Comments [0]  | 
# Monday, June 05, 2006

We are working pretty tight with our QA department. Yes, we have some well-documented work procedures but some times I feel that they are too well-documented. After all, we are lazy; We want something easy to see, easy to read & easy to do.

I thought it will be better to document our relations (Development team with QA) in a simple flow diagram:
Bug life cycle - in the eyes of a programmer.ppt (55.5 KB)

update:

I've added a step: what should I (the programmer) do if I can't reproduce the bug ?
Thanks Shani.

Maybe it will help you as well.

Posted by Oren Ellenbogen 
05/06/2006 01:21, Israel time UTC+03:00,     Comments [2]  | 
# Sunday, June 04, 2006

It's about time.

Our CTO, Roee Daliyot, is finally taking the time to write about the things he loves - GUI programming.

After writing about delegates & anonymous methods via JavaScript, he just released 2 must-see client-side controls for Drag&Drop and Clone&Drag&Drop.

So go on and pay him a visit.

Tell him I sent you.

Posted by Oren Ellenbogen 
04/06/2006 11:40, Israel time UTC+03:00,     Comments [0]  | 
# Tuesday, May 30, 2006

I need two methods which will bring me some data.

1st scenario: bring the data from the file system.

   Method name: GetData(string directory, string[] files)

2nd scenario: bring the data from a dll (assembly) file. The data is an embedded Resource inside the assembly.

   Method name: GetData(string assemblyName, string prefixPath, string[] files)


They both sit in some Helper (static)class.

Now, I thought about changing the method names into GetDataFromFS and GetDataFromAssembly. The fact that they are both serve the same purpose makes me feel that this should be a simple overload but yet I feel that this is wrong somehow due to the fact that their domain is quite different. If tomorrow I'll add GetData(string webServiceUrl, string[] files) should it be overload as well? I must say I'm not so sure...

What do you think ? overload or naming by domain[1] ?


[1] - No. I don't want some factory and concrete classes or strategy pattern implementation; This should be a simple utils class.
.NET | Design
Posted by Oren Ellenbogen 
30/05/2006 03:37, Israel time UTC+03:00,     Comments [5]  | 
# Sunday, May 28, 2006

Well, I really don't like writing posts like "Today I drank some Cola and wrote some pieces of code", but this is just funny.

I checked my Referrers list and I saw some interesting searches which lead to my blog:

1. delegate oren (www.google.com) - 1st place

   I like that phrase. delegate oren. yep, you can ring me any time. honestly!
   I guess that my lecture on delegates & anonymous methods gave me some good google PR.

Before you'll read the second one, sit down and don't hold
any glass or anything sharp in your hands.

 

2. why is teched dying (www.google.com) - 6th place

   Don't ask me why, don't ask me how, Just laugh... That's what I did.

   I have nothing but kind words to say about TechEd and you can even read some great posts here and here.

   Who is the psycho that wrote this phrase ?!?! ;-) 

3. teched 2006 party (www.google.com) - 14th place

   That's better. great party !

update:

4. porno oren (http://search.msn.fr/) - 4th place

   Oh-My-God...

5. modal refresh why god why (www.google.com) - 1st place

   Yes god, why ? well, I have a solution for this one.

Posted by Oren Ellenbogen 
28/05/2006 10:23, Israel time UTC+03:00,     Comments [0]  | 
# Friday, May 26, 2006

After receiving several messages from my friends about problems with my blog and their RSS readers I decided today to check that out. I'm using SharpReader as my RSS reader and I've noticed that my posts just don't get syndicated for some unknown reason.

The way I'm posting messages to my (das)Blog is via "Write & Save & Write" system, meaning - I write for 10 minutes, un-check "Publish" & "Syndicate" checkboxes and hit the "Post to Weblog" button. Then I click Edit on the post and continue writing. After I finish writing, I check the "Publish" & "Syndicate" checkboxes and hit the "Post to Weblog".

After playing for 2 minutes with dasBlog and trying to add\edit posts I came to the conclusion: You should *never* uncheck the "Syndicate" checkbox. This isn't reversible for some strange reason so if I want to continue using my "Write & Save & Write" system the only checkbox I should uncheck is "Publish".

Now all my old posts that were un-"Syndicate" for the first time, can not be re-syndicated.

I think that I should let Scott Hanselman know about this feature\bug, what say you ?

Posted by Oren Ellenbogen 
26/05/2006 12:06, Israel time UTC+03:00,     Comments [8]  | 
# Wednesday, May 24, 2006

We want to perform a Merge Replication between 2 databases via WebService (SSL).
The relevant Architecture for the Merge Replication is the following:

replicationviawebservice_1.jpg

Our DBA, Moran, made an attempt to configure the publisher and the subscriber according to the following links, without significant success so far:

http://msdn2.microsoft.com/en-US/library/ms345214.aspx
http://msdn2.microsoft.com/en-US/library/ms152511.aspx
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=352025&SiteID=1
http://msdn2.microsoft.com/en-US/library/ms151763.aspx
http://www.eggheadcafe.com/forumarchives/SQLServerreplication/

The error message we receive is: "The Proxy Auto-configuration URL was not found".

We think that the problem is due to local LAN proxy settings. We got the idea from this post:
http://www.eggheadcafe.com/forumarchives/sqlserverreplication/nov2005/post24306635.asp

Do you have any suggestions on the matter ?

* It's important to mention that Merge Replication over LAN works without a problem.

 

Any suggestion or reference will be most appreciated...

Posted by Oren Ellenbogen 
24/05/2006 10:42, Israel time UTC+03:00,     Comments [0]  | 
# Tuesday, May 23, 2006

Before I'll talk about a different solution, let's talk about the default solution so we could compare them.

Demonstrate the (default)missionary approach - Inheritance:

Let's view a very simple piece of code to make things a bit more tangible:

UsersDal.generated.cs file:

This file is auto-generated based on Users table from our database:

// This file is auto-generated.
// Any changes to this file can be lost in the next code generation.
// If you need to change something - check UsersDal.cs

public abstract class UsersDalBase
{
   public virtual void Add(User u)
   {
      Console.WriteLine("Doing \"base\" behavior for UsersDalBase.Add(User u)");
   }
}


You can imagine that in reality, UsersDalBase.Add method will actually open a connection against the database and insert the received user object. As you can tell, this file should be changed only by the code generator (if you change the table structure or relations for example).


Let's look at our stub class that inherit from the "Base" class.

UsersDal.cs file:

// This file is safe for edit !

public class UsersDal : UsersDalBase
{
}

This file is also generated but only as an empty stub class which can be used if we(the programmers) need to change the default behavior in UsersDalBase. Any upper layer(Business Layer, WS, whatever) in our application will use only UsersDal so any changes to UsersDal or UsersDalBase will be reflected automatically.

Now, let's say that the generated code isn't good enough. I want to check some conditions on the user object before actually adding it to our database. All I have to do is simply override the Add method in our UsersDal class.

public class UsersDal : UsersDalBase
{
   public override void Add(User u)
   {
      if (Validator.IsValid(u))
      {
         base.Add(u);
      }
      else
      {
         throw new ArgumentException("The given object is invalid.");
      }
   }
}

Now, if I want to re-generate my code due to some changes in my ERD, all I have to do is to replace the UsersDalBase.generated.cs file and my custom changes remains untouched.

The only problem with inheritance is it's limitation:

(1) You can inherit from one class only and by using inheritance I can't inherit from GenericDal (unless I'll add another layer of inheritance, not ideal).

(2) I need to give "high" access modifier(public) to my UsersDalBase. We use UsersDalBase just to allow custom changes. In a perfect world UsersDalBase should be internal (Data Access Layer project).


Let's look at a different solution - events based separation:

We want to keep our original ability to make changes in our code without losing it on the next code-generation. First, let's look at a very raw UsersEventArgs I'll use later on:

public class UserEventArgs : EventArgs
{
   private User m_user;
   private bool m_cancel;

   public UserEventArgs(User u)
   {
      m_user = u;
   }

   public User User
   {
      get { return m_user; }
      set { m_user = value; }
   }   

   public bool Cancel
   {
      get { return m_cancel; }
      set { m_cancel = value; }
   }
}

Notice the "Cancel" property, we'll use it later on.

UsersDal.generated.cs (version 2)

public partial class UsersDal
{
   protected event EventHandler<UserEventArgs> Adding;
   protected event EventHandler<UserEventArgs> Added;

   public void Add(User u)
   {
      UserEventArgs ea = new UserEventArgs(u);

      RaiseAdding(ea);

      if (!ea.Cancel)
      {
         // default logic
         AddUser(u);

         RaiseAdded(ea);
      }
   }

   protected virtual void AddUser(User u)
   {
      // generated code
      Console.WriteLine("Doing \"base\" behavior for UsersDal.Add");
   }

   protected void RaiseAdding(UserEventArgs e)
   {
      EventHandler<UserEventArgs> handler = Adding;
      if (handler != null)
         handler(this, e);
   }

   protected void RaiseAdded(UserEventArgs e)
   {
      EventHandler<UserEventArgs> handler = Added;
      if (handler != null)
         handler(this, e);
   }
}

(1) As you can see, I'm raising an event just before adding the user and another event just after adding the user.
(2) We are using partial class (UsersDal).

UsersDal.cs (version 2):

public partial class UsersDal
{
   public UsersDal()
   {
      // Register to (self) events:
      this.Adding += new EventHandler<UserEventArgs>(UsersDal_OnAdding);
      this.Added += new EventHandler<UserEventArgs>(UsersDal_Added);
   }

   protected void UsersDal_OnAdding(object sender, UserEventArgs e)
   {
      if (!Validator.IsValid(e.User))
      {
         e.Cancel = true;
         // I can also throw a new exception, that will work as well.
      }

      // If e.Cancel remains false (default) the basic (generated)behavior will be executed.
   }

   void UsersDal_Added(object sender, UserEventArgs e)
   {
      // Console.WriteLine("Doing custom UsersDal.Add - on added");
   }
}

Calling e.Cancel = true will actually stop the flow in the generated file. You can obviously add more code - according to your needs.

This separation will able you to do just about everything you could via inheritance and then some:

(1) The ability to add another partial class in order to separate class by "topics".
(2) The ability to add more listeners(event handlers).
(3) The ability to inherit from other classes, if you need to.
(4) No need for extra class in our namespace which means less confusion to the programmer - "Should I use UsersDalBase ? Oh.. wait... I remember something about it... Ya! I need to use UsersDal...".

Hope it helps.

.NET | Design
Posted by Oren Ellenbogen 
23/05/2006 11:53, Israel time UTC+03:00,     Comments [1]  | 

Nikhil Kothari, one of the coolest programmers on the planet (and one of the folks behind Atlas) came up with a brand new compiler which will basically allow you to write JavaScript via C#.
He named it Script# (pronounced: ScriptSharp).

This means you can now write JavaScript equivalent code with full IntelliSense, compile time error checking and full debugging enabled framework !!

Let me repeat (I'm hooked, sorry ;-)):

(1) No more need for alert("...") or debugger;
(2) You can compile the code and get typos errors before running the explorer and be spammed with yellow message boxes.
(3) IntelliSense people. IntelliSense. no need to open MSDN to find window or document members.
(4) I hate prototyping in JavaScript - The syntax is quite confusing and I'm lacking 2 must-have IDE features: "Go To Definition" and "Go To Reference". Now you can do it all via C#.

The idea is pretty simple. You, the developer, write C# code and compile it. Behind the scene, the Script# compiler transforms your C# code into equivalent JavaScript and create a *.js file automatically for you. This (js)file will be download to the client (you can even use the new WebResource Attribute in ASP.NET 2.0) and that's it.

You can find a set of demos, examples and of course -the binaries at Nikhil's Blog.

Fantastic !

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