# Monday, February 04, 2008

Having to parallelize almost every bit of code here at Delver, some common patterns emerged while we wrote a lot of back-end code.
I remember reading about a new framework from Microsoft Robotics Division called "Microsoft CCR" (Concurrency and Coordination Runtime) a few months ago in the "concurrent affairs" column at the MSDN Magazine but I didn't pay much attention to it at the time. Two weeks ago, it jumped back to my mind so I revisit the article and started diving a little deeper into it, thinking about what sort of problems it can solve in my world and if it does, where could I use it to our benefit. If you don't know anything about the CCR, there is great public content published already like the CCR User Guide but I'll try to give you a 2 minutes intro of the general architecture. The way CCR is built is very much like the SOA world, using messages to communicate between "services". The major components are the Dispatcher which is actually an array of OS Threads, the DispatcherQueue which holds a queue of delegates to run so the Dispatcher can "look" at the DispatcherQueue and when it has a free OS Thread available, it pulls one delegate out of the queue and run it. So far - we've got a classic ThreadPool. There are some differences but I'll let you read about it in the User Guide. The third component, which is the most important one is Port. Think about Port as a pipe that can receive messages (FIFO style - first in, first out) and hold them until someone will know what to do with them. The last component is the "manager", the Arbiter; Arbiter expose a set of methods that allows you to listen to a given pipe and if some conditions are met on the messages the pipe contains, we can take the message(s) and transform them into a runnable delegate placed in the DispatcherQueue.

One of the goals for this library is the make sure you've got much less places to go wrong, by exposing a set of common async patterns you can easily use to guarantee clean(er) code that is easier to read. Think about sending messages from one pipe to another, creating a flow-based code via messages rather than spaghetti code with a lot of messy indentation. This is a very powerful architecture.
Obviously, the entire CCR framework is thread-safe by design so no need to protect the library. A simple example:


using (Dispatcher dispatcher = new Dispatcher(5, "my_dispatcher")) //5 OS threads
using (DispatcherQueue queue = new DispatcherQueue("my_queue", dispatcher))
{
    Port<Uri> urlsPort = new Port<Uri>();
    
    Arbiter.Activate(queue,
        Arbiter.Receive(true, urlsPort, delegate(Uri uri) {
            // some code(run async!): for example we can fetch the uri content(HTML) and persist it to your Hard Disk..
         })
    );

    urlsPort.Post(new Uri("http://www.lnbogen.com"));
    urlsPort.Post(new Uri("http://www.delver.com"));
}

There is no need to create an array of Threads and some sort of Queue<Uri> in order to pull the items. The "ThreadPool" is implemented as part of the CCR.
So far no big deal right? well, it turns out that you can easily write common patterns with much less complexity: almost no locks, less spaghetti code and much less code in general.

One of the patterns we (all of us) use a lot is the "execute-and-wait-till-finish" pattern where you've got a list of independent items you want to run in parallel, but you want your main thread to wait for them to finish before continue. The simplest way to achieve it is by creating an array of Thread, activating them with a delegate and then call Join() on each one of the Threads. Let's define a few more requirements for this pattern:

  1. We want to be able to know about all the errors that occurred during the execution.
  2. We want to be able to set a timeout so each operation(inside a Thread) won't take more than a sensible time.
  3. We want to be able to know which items were timed out and when.
  4. We want to be able to know which items were completed successfully.
  5. BONUS: We want to avoid writing the obvious. 

Well, in order to implement these requirements from scratch, we need to use an outer timer with some sort of List (for example) so each thread will "register" to it when it begins and "unregister" when it's done. The timer should be able to interrupt the thread and be optimized to "wake up" as soon as possible (determined by the registered threads and which thread needs to wake up first(next in line)). In addition, we need some sort of List of exceptions to collect all the exceptions that occurred and make sure we lock shared objects. We'll need to use Thread[] and some sort of Queue to enqueue\dequeue items to\from it. A lot of code for a simple pattern.

With Microsoft CCR it's much easier.
Assuming that we want to handle a list of strings:

List<string> messagesToWorkOn = new List<string>();
for (int i = 0; i < 10; i++)
   messagesToWorkOn.Add("message " + i);

Here is the final API I've implemented on top of the CCR:

using (SpawnAndWaitPattern<string> saw = new SpawnAndWaitPattern<string>(5, "mythreadspool"))
{
   AggregatedResult<string> result = saw.Execute(messagesToWorkOn, TimeSpan.FromMilliseconds(500),
                                             delegate(string msg)
                                             {
                                                if (msg.Contains("1"))
                                                   Thread.Sleep(2000); // simulate time-out
                                                else if (msg.Contains("5"))
                                                   throw new ArgumentException("5 is a very bad value..."); // simulate exception
   
                                                Console.WriteLine("The message: " + msg + " processed successfully.");
                                             });

   Console.WriteLine("Done!");
   Console.WriteLine("Summarized Report:\n completed results: " 
      + result.SuccessfulItems.Count + "\n exceptions occurred: " + result.FaultedItems.Count 
      + "\n timed-out results: " + result.TimedoutItems.Count);
}

We've got 5 OS Threads, we're waiting for up to 0.5 second per item and we've got a full result object, holding all the requirements from above.

The code of SpawnAndWaitPattern class is quite neat and contains 0 locks (on my behalf, the CCR manage its own locks). The CCR schedule the tasks for me; combining it with thread-safe Port and we've got a very powerful yet simple framework at our hands. I decided to attach the entire solution (with A LOT of nice-green-comments) including the Ccr.Core.dll file so you could play with it:

CcrPatterns.rar (162.64 KB)

Have fun.

   

Posted by Oren Ellenbogen 
04/02/2008 06:25, Israel time UTC-07:00,     Comments [2]  | 
# Thursday, September 06, 2007

The way WCF proxies are designed is to live until shi* happens.

Let's assume that we have a CalcualtorService with one method named Divide(int a, int b). Sasha, a cool programmer-dude, trying to produce some usefull software writes:

public MyCalcualtorForm : Form {

   private
CalculatorProxy _calc = new CalculatorProxy();

   Calc_Click(...) {
      _calc.Divide(firstNumber, secondNumber);
   }
}

What is the first error you can think of that could happen? Yep, DivideByZeroException.
Once the proxy gets an exception, it enters into a "Faulted" state which makes the proxy unusable(=you cannot use it again).
The quickest solution is to work "by the book" and create a new instance each and every time we need to call the service:

Calc_Click(...) {
   using (CalculatorProxy calc = new CalculatorProxy())
      calc.Divide(firstNumber, secondNumber);
}

But what's bad in this solution?

  1. Performance - you pay (not a lot but neither little) for each creation of the proxy. Sure, it will probably not be your bottleneck, but heck, why is it useful? Most of the time the proxy will not throw an exception and yet we need to create it every time just to avoid the faulted state scenario. 
  2. Design - If we declare this exception BY CONTRACT, I would expect that the proxy will still be usable afterwards. Do we really want to return Enum\int\string as status instead of throwing exception just because of poor design?
  3. TDD - you know that I'm in love with it. Now imagine Dependency Injection. Component A recieve ICalculatorProxy and use it to... calculate something. Working "by the book" is no good as we want to recieve an instance of the proxy from the outside in order to mock it. Right, so we inject a proxy from the outside (got to love Windsor) and life is pretty sweeet. Darn! Wait! one poor (even by design) exception and our proxy goes dead. Very un-TDDish of Microsoft.

I had to come with a solution as no one will take TDD away from me. I present to you ProtectedProxy: this little IL-code-at-the-end-of-the-day will able you to recover from faulted state by creating a new proxy on each exception thus making your proxy... useable (couldn't think about a better word to describe it). Think about a situation where your proxy is trying to call the service but the service is down; In Semingo, we decided that we want to keep trying until the service is up. Via ProtectedProxy, you can determine how many times do you want to recover and when you should finally kill the proxy. Oh yea, ProtectedProxy uses Windsor in order to create new proxies if needed and logging messages to log4net. Good stuff.

In the example above, all Sasha had to do was to:
1). Initialize the _calc field by:
        ProtectedProxy<ICalculatorProxy> _calc = new ProtectedProxy<ICalculatorProxy>(new CalculatorProxy());
2). call _calc via:
        _calc.Instance.Divide(firstNumber, secondNumber);

But enough said, code please:

// Written by Oren Ellenbogen (07.08.07) - trying to protect our proxies so they could recover from:
// (A) The service is not up yet, but we want to try again later.
// (B) The service throws (ANY) exception, we still want our proxy to function (bubble the exception, but still keep on working).
// Microsoft intended to use a NEW proxy per call, but for TDD this is not ideal as we would like to inject proxies from outside as mocks
// in order to simulate multiple scenarios.

#region using

using System;
using System.Reflection;
using System.ServiceModel;
using Castle.Core.Resource;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using log4net;

#endregion

namespace Semingo.Services.Proxies.Helpers
{
   
   public interface IProxy : ICommunicationObject { 
      bool Ping();
   }

   /// <summary>
   /// Protect proxy from entering Faulted state by re-creating the proxy via Windsor Container on Faulted.
   /// IMPORTANT: that even if a fatal exception is raised by the service (for example: the service is not up yet), the proxy will be raised again. 
   /// Use it wisely (TIP: you CAN determine the number of 'recovery' attempts).

   /// </summary>
   /// <typeparam name="I">The proxy interface to protect</typeparam>
   /// <remarks>
   /// The way WCF works is that ANY exception on the service will cause the proxy to enter "faulted" state which means you can not use it anymore.
   /// Imagine a service of CalculatorService that expose the method float Divide(int a, int b). Sending b=0 will raise an exception in the service
   /// and the proxy will get into faulted state. This is not ideal as the proxy itself should be used again.
   /// </remarks>
   public class ProtectedProxy<I> : IDisposable
      where I : IProxy
   {
      private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

      private I _instance;
      private readonly IWindsorContainer _container;
      private int _faultedCounter = 0;
      private bool _disposed = false;
      private const int AlertableNumberOfFaultedTimes = 10; 

      public ProtectedProxy(I instance)
         : this(CreateXmlBasedWindsorContainer(), instance)
      {   
      } 

      public ProtectedProxy(IWindsorContainer container, I instance)
      {
         _container = container;
         ShieldInstance(instance);
      } 

      /// <summary>
      /// Returns the number of faults this proxy had so far
      /// </summary>
      public int NumberOfFaults
      {
         get { return _faultedCounter; }
      } 

      public I Instance
      {
         get
         {
            ThrowIfInstanceAlreadyDisposed(); 

            if (_instance.State == CommunicationState.Faulted || _instance.State == CommunicationState.Closed || _instance.State == CommunicationState.Closing)
               {
                  _logger.Warn("Notice: The proxy state is invalid (" + communicationObj.State + "). The Faulted event should have been raised and handle this state - this need to be checked.");
                  HandleFaultedInstance();
               }

            return _instance;
         }
      } 

      public void Close()
      {
         Dispose();
      } 

      private void ThrowIfInstanceAlreadyDisposed()
      {
         if (_disposed)
            throw new ObjectDisposedException("The protected proxy for the type: " + _instance.GetType().FullName + " was closed. Cannot return a live instance of this type.");
      } 

      private void ShieldInstance(I instance)
      {
         _instance = instance; 
         _instance.Faulted += delegate { HandleFaultedInstance(); };
      } 

      private void HandleFaultedInstance()
      {
         ThrowIfInstanceAlreadyDisposed(); 

         _faultedCounter++; 

         if (_faultedCounter >= AlertableNumberOfFaultedTimes)
            _logger.Warn("ALERT! The proxy for the type " + _instance.GetType().FullName + " got faulted for the " + _faultedCounter + " time. Recreating the proxy but we must verify if this is valid.");
         else if (_logger.IsDebugEnabled)
            _logger.Debug("Proxy for type " + _instance.GetType().FullName + " got faulted (current state: " + ((ICommunicationObject)_instance).State + ") - recreating the proxy. Number of faulted instances so far: " + _faultedCounter + "."); 

         ProxyHelper.CloseProxy(_instance); // close current proxy
         ShieldInstance(_container.Resolve<I>()); // re-create the proxy, faulted proxies are no good for further use.
      } 

      private static IWindsorContainer CreateXmlBasedWindsorContainer()
      {
         try
         {
            return new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
         }
         catch (Exception err)
         {
            _logger.Warn("Unable to create xml based windsor container, using empty one.", err);
            return new WindsorContainer(); // for testing (the proxy will be mocked anyway).
         }
      } 

      #region IDisposable Members 

      ///<summary>
      ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
      ///</summary>
      public void Dispose()
      {
         Dispose(true);
         GC.SuppressFinalize(this);
      } 

      protected virtual void Dispose(bool disposing)
      {
         _logger.Info("Attempting to dispose the protected proxy for the type: " + _instance.GetType().FullName + ", disposed already? " + _disposed); 

         if (_disposed) return

         if (disposing)
         {
            ProxyHelper.CloseProxy(_instance);
         } 

         _disposed = true;
      } 

      #endregion
   }


   public static class ProxyHelper
   {
      private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

      public static void CloseProxy(object proxy)
      {
         if (proxy == null) return
         CloseProxy(proxy as ICommunicationObject);
      } 

      /// <summary>
      /// Close the proxy in a safe manner (will not throw exception)
      /// </summary>
      /// <param name="proxy">The proxy to close</param>
      public static void CloseProxy(ICommunicationObject proxy)
      {
         if (proxy == null) return

         try
         {
            if (proxy.State == CommunicationState.Closing || proxy.State == CommunicationState.Closed || proxy.State == CommunicationState.Faulted)
               proxy.Abort();
            else
               proxy.Close();
         }
         catch (CommunicationException)
         {
            proxy.Abort();
         }
         catch (TimeoutException)
         {
            proxy.Abort();
         }
         catch (Exception err)
         {
            _logger.Error(err);
            proxy.Abort();
         }
         finally
         {
            proxy = null;
      }
   }
}

Hours of joy...

Almost forgot, on the next post - "How to TDD WCF code" - stay tuned...

.NET | TDD | WCF
   

Posted by Oren Ellenbogen 
06/09/2007 12:23, Israel time UTC-07:00,     Comments [0]  | 
# Thursday, July 12, 2007

One of the downsides of using lock is obviously performance. While locking an object, any other thread trying to acquire the lock on that object will wait in line. This can open up a deep hole to performance hit. Rule of thumb while working with locks is to acquire it as late as possible and release it as soon as possible. To demonstrate the order of magnitude bad usage of locks can affect your performance, I decided to write a little demo. 
So let's assume we have a component that is responsible for executing tasks while getting new ones in the process (on different threads). I tried to make this example as simple as possible. Let's start with our "task" class:

public class Task
{
   private int _id;
   private string _name;

   public Task(int id, string name) {
      _id = id;
      _name = name;
   }

   public int Id { // getter, setter }
   public string Name { // getter, setter }
}

We have a TasksRunner that's responsible for getting new tasks and saving it to internal list and executing the current tasks every X milliseconds (via timer). In order to simulate a real-life process, I've made sure that executing a single task is expensive. Let's start with the non-optimized solution:

public class TasksRunner
{
   private List<Task> _tasks;
   private System.Timers.Timer _handleTasksTimer;

   public TasksRunner()
   {
      _tasks = new List<Task>();

      _handleTasksTimer = new Timer(200); 
      _handleTasksTimer.Elapsed += new System.Timers.ElapsedEventHandler(_handleTasksTimer_Elapsed);
      _handleTasksTimer.Start();
   }

   public void AddTask(Task t)
   {
      lock (_tasks)
      {
         _tasks.Add(t);
         Console.WriteLine("Task added, id: " + t.Id + ", name: " + t.Name);
      }
   }

   //Execute the (delta) tasks in a thread from the ThreadPool
   private void _handleTasksTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
   {
      ExecuteCurrentTasks();
   }

   public void ExecuteCurrentTasks()
   {
      lock (_tasks)
      {
         foreach (Task t in _tasks)
            ExecuteSingleTask(t);
         
         _tasks.Clear();
      }
   }

   private void ExecuteSingleTask(Task t)
   {
      Console.WriteLine("Handling task, id: " + t.Id + ", name: " + t.Name);
      Thread.Sleep(1000); //simulate long run
   }
}

AddTask will acquire the lock on _tasks and add the new task to the list while ExecuteCurrentTasks will acquire the lock (on _tasks) and simulate real execution on the task. Notice that during the execution, calling AddTask will wait until the current execution will be finished. Using Roy's ThreadTester, we can run the following in order to notice the behavior so far:

static void Main(string[] args)
{
   TasksRunner runner = new TasksRunner();
   ThreadTester threadTester = new ThreadTester();
   threadTester.RunBehavior = ThreadRunBehavior.RunUntilAllThreadsFinish;

   Stopwatch watch = new Stopwatch();
   watch.Start();

   int numberOfTasksToCreate = 100;
   threadTester.AddThreadAction(delegate
      {
         for (int j = 0; j < numberOfTasksToCreate; j++) 
         {
            runner.AddTask(new Task(j, "job " + j));
            Thread.Sleep(100);
         }
      });

   threadTester.StartAllThreads(int.MaxValue); //wait, no matter how long

   Console.WriteLine("Total time so far (milliseconds): " + watch.ElapsedMilliseconds);
   Console.WriteLine("Tasks added so far: " + runner.TasksAdded);
   Console.WriteLine("Tasks executed so far: " + runner.TasksExecuted);
   Console.WriteLine("Waiting for tasks to end...");

   while (runner.TasksExecuted < numberOfTasksToCreate)
      Thread.Sleep(1000);

   runner.Shutdown();

   Console.WriteLine("done!");
   Console.WriteLine("Total time so far (milliseconds): " + watch.ElapsedMilliseconds);
   Console.WriteLine("Tasks added so far: " + runner.TasksAdded);
   Console.WriteLine("Tasks executed so far: " + runner.TasksExecuted);
}

Running this test will give us a very poor result for adding & executing 100 tasks takes around ~99 seconds.

No doubt, the lock on _tasks while executing each and every task in the list is too expensive as we're depend on ExecuteSingleTask (which is expensive by itself). This way, each new task we're trying to add must wait until the current execution is finished. An elegant solution to this problem, suggested by my teammate Tomer Gabel, is to use a temporal object to point to the current tasks thus freeing the lock much quicker. So here is an optimized version of ExecuteCurrentTasks:

public void ExecuteCurrentTasks()
{
   List<Task> copyOfTasks = null;
   lock (_tasks)
   {
      copyOfTasks = _tasks;
      _tasks = new List<Task>();
   }

   foreach (Task t in copyOfTasks)
      ExecuteSingleTask(t);
}

This little refactoring give us around ~11 seconds for adding & executing 100 tasks.

Smoking!

   

Posted by Oren Ellenbogen 
12/07/2007 11:44, Israel time UTC-07:00,     Comments [1]  | 
# Friday, July 06, 2007


Download and install the following:
 
Testing framework:
   NUnit (version: 2.4.1 or newer)
 
Code Coverage tool:
 
   NCover (version 1.5.8 or newer)
 
Visual Studio .Net integration tool:
 
   TestDriven.Net (version 2.7.* or newer)
 


Making it play together:
 
First of all, let me apologize for the lame example, it's kinda late for me to get creative.
Let's create a Class Library named "Calculator.Library.Tests" and write the following test in it:

[TestFixture]
public class CalculatorTests
{
   [Test]
   public void Divide_TwoValidNumbers()
   {
      Calculator c = new Calculator();

      int expected = 3;
      int actual = c.Divide(6, 2);

      Assert.AreEqual(expected, actual);
   }
}

 
Now we'll create another project(Class Library) named "Calculator.Library" and write the following code in it:

public class Calculator
{
   public int Divide(int a, int b)
   {
      if (b == 0)
         throw new DivideByZeroException("err");

      return a / b;
   }
}



Quick run of our test (print to console output):


Put the cursor in the test-method(Add_TwoValidNumbers) or in the test-class(CalculatorTests) -> right-click -> Run Test(s).

Run tests and see results in a "nice"(depends on your definition for nice) UI:
 
Right-click on the project "Calculator.Library.Tests" -> Test With -> NUnit 2.4
 
View Code Coverage:
 
Right-click on the test-method\test-class\test-project -> Test With -> Coverage. A new application named NCoverExplorer will be open - there you could explore the coverage of the code. As default, you'll see the coverage in your tests as well which is not interesting. This can be easily fixed by changing the settings in NCoverExplorer -> View -> Options... -> Exclusions (Tab) -> pattern: "*.Tests" -> Add.
 
You can see that we have 75% coverage at the moment:
 
ncoverexplorer.JPG
 
 
We can now add the following test to check the missed path (and then simply call Test With -> Coverage again):

[Test]
[ExpectedException(typeof(DivideByZeroException))]
public void Divide_TryToDivideByZero_ThrowsException()
{
   Calculator c = new Calculator();
   c.Divide(6, 0);
}

 
Easy, Fast, Free and (almost) Fully Integrated in my development environment.
Life is pretty good.
.NET | TDD
   

Posted by Oren Ellenbogen 
06/07/2007 01:13, Israel time UTC-07:00,     Comments [0]  | 
# Wednesday, July 04, 2007

One of the problems with static members or static classes is that you can't mock them for proper unit-testing. Instead of taking this fact for granted, let's demonstrate it. Assume that we have the following classes (please note, this is just an example, not production code or anything that I'll be proud of later on):

public class CsvDataExtractor
{
    private string _documentPath;

    public CsvDataExtractor(string documentPath)
    {
        _documentPath = document;
    }

    public string ExtractFullName()
    {
        string content = CsvDocumentReader.GetContent(_documentPath);
        string fullName = // extract full name logic
        return fullName;
    }
}


[Test]
public void ExtractFullName_DocumentHasFirstNameAndLastNameOnly()
{
    CsvDataExtractor extractor = new CsvDataExtractor("c:\test.csv");
    
    string result = extractor.ExtractFullName();
    
    Assert.AreEqual("ellenbogen", result);
}

 
This test is not good as we can't test the ExtractFullName by itself - we're testing that CsvDocumentReader.GetContent works as well. In addition, we're depend on external file because this is what CsvDocumentReader.GetContent expects to receive.
 

Here are our options to solve this dependency so we could test ExtractFullName method by itself:
 
1). Refactor the static class into "instance" class and implement some sort of IDocumentReader interface.

Now CsvDataExtrator can get IDocumentReader in its constructor and use it in ExtractFullName. We could mock the interface and determine the result we want to get from the mocked object. Here is the refactored version:

public interface IDocumentReader
{
   string GetContent(string documentPath);
}

public class CsvDataExtractor
{
   private string _documentPath;
   private IDocumentReader _reader;

   public CsvDataExtractor(IDocumentReader reader, string documentPath)
   {
      _documentPath = document;
      _reader = reader;
   }

   public string ExtractFullName()
   {
      string content = _reader.GetContent(_documentPath);
      string fullName = // extract full name logic
      return fullName;
   }
}

[Test]
public void ExtractFullName_DocumentHasFirstNameAndLastNameOnly()
{
   DocumentReaderStub reader = new DocumentReaderStub();
   reader.ContentToReturn = "oren,ellenbogen";

   CsvDataExtractor extractor = new CsvDataExtractor(reader, "not important document path");

   string result = extractor.ExtractFullName();

   Assert.AreEqual("ellenbogen", result);
}

internal class DocumentReaderStub : IDocumentReader
{
   public string ContentToReturn;
   public string GetContent(string documentPath) { return ContentToReturn; }
}

 
Pros: (1) We can use mocking framework (Rhino Mocks for example is a great choice, and I'm not getting payed for it. I swear) to create stubs\mocks really fast and almost with no code. (2) Static classes and static members can not be easily tested, so we can save a few painful minutes\hours to the our teammates by refactoring now. (3) This one relates to reason 1 - If we need to mock several methods of our static class CsvDocumentReader, this is a better solution as we can achieve it easily with mocking framework.
Cons: (1) It's not always possible to refactor the original static class. For example, we can't change Microsoft's Guid static class to control NewGuid() method, assuming that we need to mock it.
 
2). Wrap the static class with an instance class and delegate calls:

We can create an interface that expose all the functionality of the static class. Then all we need to do is wrap it with a simple class that will delegate the calls to the static class:

// the interface should look exactly like the static class we want to wrap !
public interface IDocumentReader
{
   string GetContent(string documentPath);
}

// This class will simply delegate calls to the static class
public class CsvDocumentReaderWrapper : IDocumentReader
{
    public string GetContent(string documentPath)
    {
        return CsvDocumentReader.GetContent(documentPath); // call the original static class
    }
}


The CsvDataExtractor implementation and the tests are exactly the same as option 1.
 
Pros: You can enjoy all the Pros of option 1.
Cons: (1) Wrapping is costly performance and especially in maintenance. In addition, you suffer from all of the Cons of option 1.

 
3). Use "protected virtual" method to call the static member and override it:

public class CsvDataExtractor
{
   private string _documentPath;

   public CsvDataExtractor(string documentPath)
   {
      _documentPath = document;
   }

   public string ExtractFullName()
   {
      string content = GetDocumentContent();
      string fullName = // extract full name logic
      return fullName;
   }

    protected virtual string GetDocumentContent()
    {
        return CsvDocumentReader.GetContent(_documentPath);
    }
}

[Test]
public void ExtractFullName_DocumentHasFirstNameAndLastNameOnly()
{
   TestableCsvDataExtractor extractor = new TestableCsvDataExtractor("not important document path");
   extractor.ContentToReturn = "oren,ellenbogen";

   string result = extractor.ExtractFullName();

   Assert.AreEqual("ellenbogen", result);
}

public class TestableCsvDataExtractor : CsvDataExtractor
{
    public string ContentToReturn;
    
    public TestableCsvDataExtractor(string documentPath) : base(documentPath)
    {
    }
    
    protected virtual string GetDocumentContent()
    {
        return ContentToReturn;
    }
}

Pros: (1) if we can't refactor the original static class - it's a very fast & simple  solution to use (.vs. wrapping it).
Cons: (1) Not a perfect solution from an "elegant code" prospective.
 
 
 
I love to use option 3 if refactoring is too hard to (or not possible to) achieve but no doubt, option 1 will give you the best results if you're looking a few steps ahead.
.NET | TDD
   

Posted by Oren Ellenbogen 
04/07/2007 01:12, Israel time UTC-07:00,     Comments [1]  | 
# Monday, June 25, 2007

In my last post, I wrote about Implementing a simple multi-threaded TasksQueue. This post will concentrate in how to test for Thread Safety of the queue. Reminder: our queue is used by multiple consumers which means that I must make sure that before each Enqueue\Dequeue\Count, a lock will be obtained on the queue. Imagine that I have 1 item in the queue and 2 consumers trying to dequeue this item at the same time from different threads: The first dequeue will work just fine but the second will throw an exception (dequeue from an empty queue). We're actually trying to make sure that this queue works as expected in multi-threaded environment. So far about our goal.

So how can we test it?
Testing for the queue's thread safety through testing of TasksQueue, the way it's written now, can be quite hard and misleading. The ConsumeTask method calls dequeue inside a lock but what if we had a thread-safety-related-bug there? do we test only that the dequeue works as expected? not really. ConsumeTask (1) dequeue an item and then (2) "consume it". We're actually testing 2 behaviors\logics - this way, it's really hard to test only for the queue's thread safety. We should always test a single method for a specific behavior and eliminate dependencies. Only when we cover our basis, we can check for integration between multiple components (the underlying queue and the TasksQueue).

One way of allegedly achieving this goal is to create a decorator around the queue, let's call it SafeQueue, which will encapsulate a queue and wrap it with thread-safe forwarding of the calls (it will lock some inner object and call the original queue). The SafeQueue could be tested then by its own and used by our TasksQueue. This will "enable" us to remove the locking in the TasksQueue and use Set\WaitOne instead of Pulse\Wait in order to notify our consumers on arrival of a new task: 

while (_safeQueue.Count == 0)
   Monitor.WaitOne();

// NOTICE: by the time we get here, someone could have pulled the last item from the queue on another thread!
string
item = _safeQueue.Dequeue();

WATCH OUT: This is a deadly solution that will make our TasksQueue break in a multi-threaded environment. Just like that, our code is not thread-safe anymore although we're using a SafeQueue that expose (atomic) thread-safe methods\properties. This is exactly why instance state should not be thread-safe by default (more details at Joe Duffy's post).

The locking of the queue should remain in our TasksQueue, but we should separate the dequeue part from the handling part and check each one by its own. We'll check the dequeue part for thread-safety(assuming that the underlying queue was tested by itself) and the handling part for pure logic. We can now test that for X calls for enqueue we get the same X calls for dequeue.

Here is the refactored code:

private void ConsumeTask()
{
   while (true)
   {
      string task = WaitForTask();

      if (task == null) return; // This signals our exit

      try
      {
         // work on the task
      }
      catch (Exception err)
      {
        // log err & eat the exception, we still want to resume consuming other tasks.
      }
   }
}

protected virtual string WaitForTask()
{
   lock (_locker)
   {
      // if no tasks available, wait up till we'll get something.
      while (_queue.Count == 0)
         Monitor.Wait(_locker);

      // try to put it outside of the lock statement and run the test(bellow)
      return
_queue.Dequeue(); 
   }
}

public virtual void EnqueueTask(string task)
{
   lock (_locker)
   {
      _queue.Enqueue(task);
      Monitor.Pulse(_locker);
   }
}

Now we can create a simple test for the thread safety by overriding both of the enqueue\dequeue methods:

internal class TestableTasksQueue : TasksQueue
{
   private static int _dequeueCount = 0;
   private static int _enqueueCount = 0;

   public TestableTasksQueue(int workerCount) : base(workerCount) {}

   protected override string WaitForTask()
   {
      string item = base.WaitForTask();
      Interlocked.Increment(ref _dequeueCount);
      return item;
   }

   public override void EnqueueTask(string task)
   {
      base.EnqueueTask(task);
      Interlocked.Increment(ref _enqueueCount);
   }

   public static int DequeueCount
   {
      get { return _dequeueCount; }
   }

   public static int EnqueueCount
   {
      get { return _enqueueCount; }
   }
}

The tricky part here is the test itself. Because of subtle multi-threading issues, we can't actually know when 2 (or more) threads will try to dequeue on the same time, so we have to run this test enough times in order to detect bugs. Here is a little sample:

[TestFixture]
public class TasksQueueTests
{
   [Test]
   public void Counting_DequeueAndEnqueueCountsShouldBeEqual()
   {
      for (int j = 0; j < 1000; j++)
      {
         using (TestableTasksQueue queue = new TestableTasksQueue(5))
         {
            for (int i = 0; i < 100; i++)
               queue.EnqueueTask("test" + i);
         }

         Assert.AreEqual(TestableTasksQueue.DequeueCount, TestableTasksQueue.EnqueueCount);
      }
   }
}

Well, it's not that elegant, I know, but thread-safety is hard to test.
I would love to hear some suggestion from you regarding this issue.

   

Posted by Oren Ellenbogen 
25/06/2007 02:39, Israel time UTC-07:00,     Comments [0]  | 
# Sunday, June 17, 2007

In one of my tasks, I had to create a simple mechanism that will able my Team to enqueue tasks, while multiple threads will work on them on the background. I've used the Wait\PulseAll pattern in order to signal the workers when a new task is available. Here it goes:

public class TasksQueue : IDisposable
{
   private readonly object _locker = new object();
   private Thread[] _workers;
   private Queue<string> _tasksQueue = new Queue<string>();

Nothing fancy so far. Just notice that we're holding a private lock object and an array of Thread that will represent our workers.
The constructor simple initialize the threads and activate them:

public TasksQueue(int workerCount)
{
   if (workerCount <= 0) throw new ArgumentException("The number of working threads can not be equal or less than 0", "workerCount");
   
   _workers = new Thread[workerCount];
   for (int i = 0; i < workerCount; i++) { // Create and start a separate thread for each worker
      Thread workerThread = new Thread(ConsumeTask);
      workerThread.Name = "WorkerThread #" + i;
      _workers[i] = workerThread;
      workerThread.Start();
   }
}

I've bold the "ConsumeTask" method that each Thread activates. Let's see what we have there:

private void ConsumeTask()
{
   while (true)
   {
      string task;
      lock (_locker)
      {
         // if no tasks available, wait up till we'll get something.
         while (_tasksQueue.Count == 0) {
            // Monitor.Wait is equal to:
            // (1) Monitor.Exit(locker); (give others a chance to lock _locker) 
            // (2) wait for pulse 
            // (3) on pulse - Monitor.Enter(locker);
            Monitor.Wait(_locker); 
         }

         // The first working thread that will be pulsed will reacquire the lock on "locker", thus
         // it's impossible that 2 working threads will try to dequeue the same task.
         task = _tasksQueue.Dequeue();
      }

      if (task == null) return; // This signals our exit

      try
      {
         Console.WriteLine(DateTime.Now + " Start Processing task: " + task + " on thread: " + Thread.CurrentThread.Name);
         // Simulate a time-consuming task
         Console.WriteLine(DateTime.Now + "Done Processing task: " + task + " on thread: " + Thread.CurrentThread.Name);
      }
      catch (Exception err)
      {
         // log err & eat the exception, we still want to resume consuming other tasks.
         //Debug.Fail("Exception occurred while trying to consume the job (thread#: " + Thread.CurrentThread.Name + "): " + err.Message);
      }
   }
}

We're looping(infinite) and trying to see if our queue is empty - if so, we're waiting for a new task to arrive. Till then - the thread will be blocked(inactive). When we have a new task (or the queue is not empty), we dequeue a task and "process" it. Let's see the Enqueue method:

public void EnqueueTask(string task)
{
   lock (_locker)
   {
      if (task != null)
         Console.WriteLine(DateTime.Now + " Enqueue task: " + task);

      _tasksQueue.Enqueue(task);
      Monitor.Pulse(_locker); // wake 1 worker (thanks Alan) to handle the new task
   
   }
}

This leaves us with disposing the all thing (killing our threads gracefully):

public void Dispose()
{
   EndCurrentWorkingThreads();
}

private void EndCurrentWorkingThreads()
{
   if (_workers == null || (_workers != null && _workers.Length == 0))
      return;

   // Signal the threads to shutdown gracefully
   for (int i = 0; i < _workers.Length; i++)
      EnqueueTask(null); //will shutdown the worker that receive a null task.

   // Wait up...
   foreach (Thread worker in _workers)
      worker.Join();
}

That's it, but how can we use it you might ask - here it goes:

using (TasksQueue q = new TasksQueue(2))
{
   for (int i = 0; i < 10; i++)
      q.EnqueueTask("Task " + i);

   Console.WriteLine("Waiting for completion...");
}

Console.WriteLine("All tasks done!");

   

Posted by Oren Ellenbogen 
17/06/2007 11:00, Israel time UTC-07:00,     Comments [4]  | 
# Tuesday, June 12, 2007

Every new application we're trying to raise from scratch, especially when it's a big one, we're drawn to the basic questions of how to structure our code so it will be easy to maintain, easy to extend and easy on the eyes(= it makes sense). This post is meant for teams with more than 4 programmers working on the source of a 2+ (human) years project. If you work alone and the client doesn't really care, heck, you can do it in one big assembly and name it [your_name]Rules.

I've discovered along the years that it really bothers me to see unorganized solutions or bad naming. I call it "structure smell" and as you might have guessed, I'm a sensitive guy. I've structured my thoughts about the way I see things so I could use it later on as a reference for myself and for my Team. Before I'll continue, keep in mind that most of these questions are philosophical, so there is no one holy answer, it's just a matter of point of view. I tried to point out best practices based on my experience. In addition, instead of writing user-story\feature\requirement\bug fix\UI change\you-name-it, I would use the term "task" instead. I'll even go one step further and say that a given task should be limited to 0.5-1.5 days so it would be easy to see progress over time(if you're on the agile boat as I am) and help us focus on the domain\context we're working at during the task.

Enough said, let's get going:

"Should we build one big solution?"

The immediate answer on this one is absolutely not.
The quick reason behind it as no matter what you do, while working on a task, you usually don't need all of the projects at the same time. I see no reason to compile so many projects if you're working only on 2-3(or even 5-6) of them at a time. I know that Visual Studio .Net is smart enough to avoid needless compilation of projects that we're not changed, but keep in mind that John, your teammate, is working on different tasks than you are which means that he can make some changes, checked them in and your next "Get Latest Version" might cause unnecessary compilation on your side. If you haven't noticed(who am I kidding), VS.NET can become an heavy memory consumer for big solutions, add to it our beloved ReSharper(that must analyze all of the projects in the solution to give you smart ideas), it can get quite messy.

The second reason, is simplicity. Why looking at 40 projects when you need only just a few? sure, you can collapse them or even organize them in Solution Folders(in VS.NET 2005), but it's much easier to keep the noise out.

"So How should we split our solutions and projects?"

On this scale of projects, it would not be a great idea to create projects based on layers (DataAccess project, Business layer project, UI project etc). This way, each layer(=ClassLibrary) would be filled with too many classes and in time, it will be hard to find your path in one project with more than 200 files in it. Another bad side effect for splitting the projects by layers is that it will narrow the way you think about solutions (to problems). Instead of trying to create pure OO components you'll immediately start breaking one piece into "this is UI, this is BL, this is DAL" and possibly branch your code into the wrong assemblies by cold 0 or 1 decisions. Life is one big gray CLR.

So I'll try to define the way I see solutions, projects and namespaces and how should we use them:

1). Solution represent a domain in your application.

Domain is a complete sub-system in the application. It's much bigger than a single component and it's usually bind a list of components into one large sub-system that we can address as one big black box. The sub-system expose interfaces to other sub-systems in the application.

If I had to develop Lnbogen's Calendar for example, I would consider these sub-systems: Common, Engine, DataStorage, Site, Widgets. Each one of these sub-systems deserves it's own solution.

2). Project is a component in that domain or a mini-sub-system in the application.

A component is a all-around solution in a specific domain. The consumer of the component expect it to perform its task from A-Z even if that requires some of interaction with other objects. It should be transparent to the component's consumer. Let's say that we have a Calendar component, I would like to be able to call myCalendar.CreateNewMeeting(user, [meeting details]...) without taking care of insert it to the database, update some sort of cache(if exists) or to trigger alerts manually in case of collision. I expect the component to provide a full solution to my problem. Obviously, we don't expect the Calendar to save the meeting to the data storage by it's own but rather to receive some sort of IDataSource that will take care of it, but that should be made behind the scene as the purpose is to expose complete functionality.

In addition, a project might be "Entities" or "Utilities" where in these scenarios, the project represent a mini-sub-system.

3). Namespace group components and types under the same domain or "logic context"

Namespaces allow us to group types that are logically belong to the same domain and create a proper hierarchy so the programmer could easily find is way around the available types.

"What about naming?"

Naming is crucial for a few reasons: (A) It ables us to quickly understand the purpose of an assembly\class\method as its consumers, (B) good naming of classes\methods => less documentation => more 1:1 between your docs & your code and (C) it helps you to keep the most important principle of coding - be proud of your (and your team's) code. It's a beautiful thing to see Semingo.[...]. I'm loving it!

Naming rules:
1). Name your solutions by the domain they represent.
2). Name your projects by the components or mini-sub-system they represent. Template: [CompanyName].[Application].[ComponentName\MiniSubSystem]
3). Name your namespaces by the domain they group (the types) by.


Example (Lnbogen's Calendar):

Directories tree:

- Lnbogen
 - Calendar (root Directory)
   - build
      - v1.0
      - v1.1
      (etc)
   - tools
      (list of assemblies, exe or other 3rd party components you might use)
   - documents
   - db
      (maybe backup of database files for easy deployment)
   - src
      - Common
         | Common.sln
         - Lnbogen.Calendar.Entities 
         - Lnbogen.Calendar.Entities.Tests 
         - Lnbogen.Calendar.Utilities            
         - Lnbogen.Calendar.Utilities.Tests 
      - Engine
         | Engine.sln
         - Lnbogen.Calendar.Framework
         - Lnbogen.Calendar.Framework.Tests
         - Lnbogen.Calendar.TimeCoordinator
         - Lnbogen.Calendar.TimeCoordinator.Tests
         - Lnbogen.Calendar.RulesEngine
         - Lnbogen.Calendar.RulesEngine.Tests
         - Lnbogen.Calendar.Service (*1)
         - Lnbogen.Calendar.Service.Tests
      - DataStorage
         | DataStorage.sln
         - Lnbogen.Calendar.DataStorage.Framework
         - Lnbogen.Calendar.DataStorage.Framework.Tests
         - Lnbogen.Calendar.DataStorage.HardDiskPersisenceManager
         - Lnbogen.Calendar.DataStorage.HardDiskPersisenceManager.Tests
         - Lnbogen.Calendar.DataStorage.WebPersisteneceManger
         - Lnbogen.Calendar.DataStorage.WebPersisteneceManger.Tests
         - Lnbogen.Calendar.DataStorage.DatabasePersistenceManager
         - Lnbogen.Calendar.DataStorage.DatabasePersistenceManager.Tests
         - Lnbogen.Calendar.DataStorage.Service (*1)
         - Lnbogen.Calendar.DataStorage.Service.Tests
      - Site
         - Lnbogen.Calendar.UI
         - Lnbogen.Calendar.UI.AdminSite
         - Lnbogen.Calendar.UI.UserSite
      - Widgets
         - Lnbogen.Calendar.Widgets.Framework
         - Lnbogen.Calendar.Widgets.Interfaces (for plug-ins support)
         - Lnbogen.Calendar.Widgets.Service
         (more directories per widget)
      - Integration
         - Lnbogen.Calendar.Integration.InternalWorkflow.Tests 
         - Lnbogen.Calendar.Integration.ExternalWorkflow.Tests (test that the services we expose to the world work as expected)
      - References
         (here you should put all the dlls that you use as "file reference" in the various solutions)
         
*1: for example, this could be WCF wrapper of the underlying engine that enable other internal components to talk with the CalendarEngine\DataStorage as one complete component.

You can notice that I've chosen to drop the "Engine" or "Common" while selecting the name of the directories. "Common" is not really a domain but rather a logic separation of things that belong to many domains (usually all of them). "Engine" is the real deal, there is no Calendar without the engine right? So in this case I feel comfortable to drop the obvious (Lnbogen.Calendar.Framework won't sound better as Lnbogen.Calendar.Engine.Framework).

Solution structure:

In VS.NET 2005, there is a nice feature named "Solution Folder" (right-click on the solution->Add->New Solution Folder) which is a lovely way to group projects. The Solution Folder is a virtual folder(you won't see it on your HD) so you don't have to get worried about too much nesting. 

Here is the pattern I love to use, demonstrated on the Engine.sln:

Engine (Solution)
   _Core (Solution Folder) (*2)
      - Lnbogen.Calendar.Framework
      - Lnbogen.Calendar.TimeCoordinator
      - Lnbogen.Calendar.RulesEngine
      - Lnbogen.Calendar.Service
   Tests (Solution Folder)
      - Lnbogen.Calendar.Framework.Tests
      - Lnbogen.Calendar.TimeCoordinator.Tests
      - Lnbogen.Calendar.RulesEngine.Tests
      - Lnbogen.Calendar.Service.Tests
   ExternalComponents (Solution Folder)
      - Lnbogen.Calendar.Entities (via "Add existing project")
      - Lnbogen.Calendar.Utilities (via "Add existing project")
   3rdPartyComponents (Solution Folder)
      - (Open Source projects that I might use will go here)
   Solution Items
      (add any dll that you use as file reference in this solution)

*2: The reason I'm using "_" is to make sure it's the first Solution Folder. I just think it's more productive way of looking on your projects. I use the same thing for my interfaces and call the file that contains them _Interfaces.cs.


On the next post, I'll try to focus on strong naming and versioning of assemblies.

.NET | Articles | Design
   

Posted by Oren Ellenbogen 
12/06/2007 06:41, Israel time UTC-07:00,     Comments [2]  | 
# Wednesday, May 02, 2007

Damn, it was so much fun to play a little with TDD and abstract the lousy API given by Microsoft to register client-side script. I'll write about the process and design changes I've made due to testability reasons. TDD is a great design tool, it's amazing to witness the "before" and "after" of your code, all because of the requirements to test things separately.

Here are a few API samples, taken from the Demo project (you can play with it and see the results):

public partial class _Default : Page
{
   protected void Page_Load(object sender, EventArgs e)
   {
      ClientSideExtender script = ClientSideExtender.Create(this);

      script.RegisterMethodCall("alert").WithParameters("hello world!").ToExecuteAt(Target.EndOfPage);

      script.RegisterVariable<string>("myStringVar").SetValue("test").ToExecuteAt(Target.EndOfPage);
      script.RegisterVariable<int>("myIntegerVar").SetValue(5); // Target.BeginningOfPage as default

      script.RegisterScriptBlock("alert('proof of concept - state:' + document.readyState);").ToExecuteAt(Target.PageLoaded);
   }
}

Keep in mind that I'm only supplying a different API (abstraction) of Microsoft's implementation. In order to accomplish that, I'm using Windsor to wire the ClientSideExtender with the new ajaxian ScriptManager(supports UpdatePanel), which will actually be responsible to register the script under the hood. You can look at the web.config (under the <castle> element) for more details.

Source:
Lnbogen.Web.UI.zip (253.56 KB)

.NET | Design | JavaScript | TDD
   

Posted by Oren Ellenbogen 
02/05/2007 02:05, Israel time UTC-07:00,     Comments [1]  | 
# Friday, April 27, 2007

Phil Haack gives an excellent example of how to test a registration to event while implementing MVP pattern (via Rhino Mocks). If you did not read it yet, take a pause for 2 minutes and give it a look; It is worth it, I promise.

The only thing that bothers me in the example is that the need to assert the triggering of the event kind of spoiled the code. I think that in those scenarios, it's much better to use some sort of Stub and override the class under test in order to keep the it cleaner. So instead of having this code:

public class Presenter
{
   IView view;
   public Presenter(IView view)
   {
      this.view = view;
      this.view.Load += new EventHandler(view_Load);
   }

   public bool EventLoaded
   {
      get { return this.eventLoaded; }
      set { this.eventLoaded = value; }
   }

   bool eventLoaded;

   void view_Load(object sender, EventArgs e)
   {
      this.eventLoaded = true;
   }
}


I would have created something like this:

public class Presenter
{
   IView view;
   public Presenter(IView view)
   {
      this.view = view;
      this.view.Load += new EventHandler(view_Load);
   }

   protected virtual void view_Load(object sender, EventArgs e)
   {
       // production code here
   }
}


// This will go in the PresenterTests class
public class TestablePresenter : Presenter
{
   public bool WasEventLoaded = false;
   protected override void view_Load(object sender, EventArgs e)
   {
       WasEventLoaded = true;
   }
}


Now we can create an instance of TestablePresenter and Assert the WasEventLoaded field.
My guess is that Phil actually did something like this in his project and merely wanted to show an example, but I still thought it was important enough to demonstrate this separation as I firmly believe we must make sure that our need for tests will not actually hurt the design.

.NET | TDD
   

Posted by Oren Ellenbogen 
27/04/2007 10:55, Israel time UTC-07:00,     Comments [2]  | 
# Saturday, April 21, 2007

In my last post about Creating a decent API for client side script registration, Eran raised a few great comments about the readability and proper usage of this style of coding. I decided to answer his questions with a post, as my comment started to fill enough paper to clean a Brazilian forest or two (well, in terms of a response).

Introduced by Martin Folwer, Fluent Interfaces ables the programmer to supply an API that can be used to build a genuine use-case in the system or just a complete logical query\request from a service. This coding style is quite different from the traditional 101 lessons in OOP school. The biggest benefit of Fluent Interface, in my opinion, is that you can read the code out load like the customer is talking to you instead of the programmer that wrote it. Sometimes it gets even better, you can read someone's else code like she\he was next to you, explaining what she\he meant do do. My take is that using a method to describe use-case\action\query\request will be (almost)always better, in terms of readability, than using parameter(s) as you'll need the IntelliSense to understand the latter. Here is a simple API, the first one is traditional OOP while the second one applies Fluent Interfaces. Please bare in mind that these samples were written just to set the ground for the difference between these two coding technique:

// take 1 - traditional style
public class ClientSideExtender
{
    public void CallMethod(string methodName, RunAt runScriptAt, bool ignoreExceptions, params object[] parameters);
}


// take 2 - Fluent Interfaces

public class ClientSideExtender
{
   public ScriptCommand CallMethod(string methodName);
}

public class ScriptCommand
{
     public ScriptCommand WithParameters(params object[] parameters);
     public ScriptCommand When(RunAt runScriptAt);
     public ScriptCommand IgnoreExceptions();
}

Assuming that we have a javascript method with this signature "markRow(rowId, shouldDisableOtherRows)", here is how can one use these API to register client-side method call(accordingly):

clientSideExtender.CallMethod("markRow", RunAt.AfterPageLoaded, true, "5", true);

clientSideExtender.CallMethod("markRow").WithParameters("5", true).When(RunAt.AfterPageLoaded).IgnoreExceptions();


Obviously, both API will create the same code eventually: <script ...>markRow("5", true);</script>.
What I really love about Fluent Interfaces is that I don't need the freakin' IntelliSense in order to understand what "true" means as a parameter(the difference is marked in red). It ables me to read it out load - I want to call a client-side method named "markRow", with 2 parameters, execute it after the page is loaded and wrap the entire thing to swallow exceptions (assume that someone else will take care of it). If you want to call a method that doesn't get any parameter, don't call to WithParameters method. You can always change the order of the calls if you see it fit (maybe calling IgnoreException before When).

One of the blames I hear(again and again) about Fluent Interfaces is that it "allows" programmers to abuse the code. "You can change the order of the calls or forget to call one and make a big mess" is a common response to the concept. To be totally honest, I don't eat it as programmers can make a mess of pretty much anything. We've all been there, right? I agree that it requires some different way of thinking about creating & using API, but then again, so does learning a new programming principle, a design pattern or a coding techinque. It took several years until people started to chew TDD and accept the advantages of using it. My guess is that in ~1-2 years, Fluent Interfaces will be much more common in the way we're writing and using code (LINQ rings a bell? well OK, leaving the "sql-like" synthetic sugar aside).


This leads me to my believe about designing Fluent Interface. I say - when appropriate, why not allowing the programmer to choose?
I would create two overloads for CallMethod, as shown above, and let the programmer decide which one she\he would like to use.

I would use Fluent Interface.

.NET | Design
   

Posted by Oren Ellenbogen 
21/04/2007 11:04, Israel time UTC-07:00,     Comments [6]  | 
# Wednesday, April 18, 2007

I'll start my post with a question:
What's the difference between ScriptManager.RegisterClientScriptBlock and ScriptManager.RegisterStartupScript methods?

Well, the only way to find out is not by looking at the method names but rather to look in MSDN. According to MSDN the former registers your script after the <form> element while the latter is registering your script just before the </form>. Now, let me ask you this - how the word "Startup" can be interpreted as "end of page"?

So OK, the naming is really bad but what's even worse are the arguments of these methods:

public static void RegisterClientScriptBlock(Control\Page control\page, Type type, string key, string script, bool addScriptTags);
public static void RegisterStartupScript(Control\Page control\page, Type type, string key, string script, bool addScriptTags);

Now, most of us write this code 95%(+) of the times:

ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "some stupid key", "the script here, finally...", true); //like someone is stupid enough to give false - if you have a full script, why not putting it inside myFile.js and add it to the header?

I don't understand the real need behind creating a "unique" key from the type+key given to this method. Why not creating a unique key each and every time? You need to create a simple API for the common (90%) tasks. I almost never actually asked about IsClientScriptBlockRegistered. But enough complaining, time to write a few bits & bytes.

I tried to play with the API a little and here is what I came up with (it's merly the beginning, I'll update on my progress during the week):

PageClientSideExtender clientSide = new PageClientSideExtender(Page);

// A better approach, IMHO, to ScriptManager API
clientSide
  .RegisterScript("alert('run at the beginning of the page');")
  .AddScriptTags()
  .RunAtTheBeginningOfThePage();

clientSide
  .RegisterScript("<script>alert('run at the end of the page');</script>")
  .RunAtTheEndOfThePage();

//let's register something like:
// var width = 300;
clientSide.RegisterLocalVariable<int>("width").SetValue("someValue");

//let's register something like:
// var data = 'width:300;height:500';
clientSide.RegisterLocalVariable<string>("data").SetValueFormatted("width:{0};height:{1}", 300, 500);

// Let's register to the onload of the <body> and trigger a nice alert
clientSide.Body.Load += ClientSideScriptHelper.CreateHandler("alert('run on body onload! cool ah??');");


//Or:

clientSide.Body.Load += delegate { return "alert('another message shown after the page onload event was raised. sweet!');"; };


The Fluent interface gives it a nice "read-the-code-like-a-story" look&feel which makes things really easy to understand. There is no thinking here, the code says it all.

Another rant I have is that all of the API examples I've demonstrated so far are implemented although not fully tested as using Microsoft classes requires a lot of work in order to abstract. The funny thing is that they(Microsoft) have decoupled things in the new Microsoft ASP.NET Ajax library(System.Web.Extension.dll) but they made everything internal!  You have IPage, which is really useful abstraction to the Page class, sitting there as an internal member. I had to come up with some heavy abstraction to make things play nice together.

To sum up, I would really appreciate YOUR feedback about the API and any kind of suggestion or things that you would like to see in future API. I'll release the code later this week with a short demo to get you going.

   

Posted by Oren Ellenbogen 
18/04/2007 11:08, Israel time UTC-07:00,     Comments [5]  | 
# Wednesday, April 04, 2007

One of my favorite C# 3.0 features is Extension Methods. In short, it ables you to extend an existing type with additional behaviors. For example, you can consider to extend the type System.Int32 (aka "int") with a new method named IsEven.

The syntax is quite trivial:

namespace Lnbogen.Extensions
{
    public static class Extentions
    {
        public static bool IsEven(this int i)
        {
            return ((i%2)==0);
        }
    }
}

Notice the "this int" which means "I want to extend the type int".
Now I can write the following code (fully IntelliSense-d and compile time checking):

using Lnbogen.Extensions; //<- this will load the extensions, it won't compile without it!

... void TestIsEven()
{
   int num = 5;
   Console.WriteLine(num.IsEven());
}

What's going on behind the scenes is quite simple, the compiler got a little "smarter" and now knows to look for Extension Methods in the imported namespaces. I don't want to elaborate too much about the syntax and requirements as Anders Hejlsberg makes it all clear in his MSDN video: C# 3.0: Future Directions in Language Innovation.


Let me direct you to the  real  meat:


Extension Methods is going to change the way we enhance "already used" code. Up to now, looking at that need (for backward compatibility), Microsoft suggested to create an interface and an abstract class that implement this interface. This allows us to extend the abstract class simply by providing new virtual members without breaking the code. The problem in this solution is that things were getting out of sync really fast leaving our interfaces shy & dry(=out of date), just to avoid breaking changes. Even worse, due to the fact that multi-inheritance is forbidden, inheriting from the abstract class pretty much slammed the door on most of our design choices. 

Let's face it; Interfaces were programmer's nightmare(before you hack my blog and delete this post, bare with me). On one hand, we're reluctant to implement an interface with 10 members as we prefer to finish our tasks in this century but on the other hand, we want our interface to expose as much API as it can to allow easy usage for its customers(=programmers) and to avoid casting it(the interface) to "specialist" interfaces.

Well, Extension Methods allows us to extend any type. Do you get my drift here?
You can now enhance any interface you've ever exposed thus making old interfaces incredibly strong. You can define a lightweight interface(easy for the implementor of the interface) and extend its abilities without breaking any existing code(enrich the customers of the interface). This is exactly what Microsoft did with LINQ. They have extended IEnumerable<T> with many Query methods such as "Select", "From", "Where", "GroupBy", "Join" (and much more...) to enhance it with a great set of new methods while still keeping the original interface untouched. All we have to do is simply import System.Query namespace.


Brilliant.

.NET | C# 3.0
   

Posted by Oren Ellenbogen 
04/04/2007 07:01, Israel time UTC-07:00,     Comments [2]  | 
# Tuesday, January 16, 2007

After digging in into BitArray with Reflector, I saw that this class, in its current state, is simply unusable; Here is why:

1.  The class does not override Equals (and ==, !=, GetHashCode). We use BitArray because bitwise comparison is relatively very fast. I don't want to perform reference comparison on bitwise array. I use bitwise structure to perform bitwise operation and bitwise comparison.

2.  This class is sealed.  Reading the first section can give you the idea why this is a mistake built on top of another mistake.

3.  The exposed bitwise operations change the state of the object. Meaning doing bitArrayInstance.And(anotherBitArray) actually change the state of bitArrayInstance. I really don't understand why this was made by design. It is very common to perform several bitwise operations on a BitArray object and perform some comparison afterwords.

We decide to disassemble the code into a new class named BitArray2 and I refactored the code so it would fit the "normal"(in my book) usage of BitArray.
The code:

BitArray2.zip (4.19 KB)
   

Posted by Oren Ellenbogen 
16/01/2007 10:33, Israel time UTC-07:00,     Comments [1]  | 

I have to following code:

BitArray arr1 = new BitArray(200);
BitArray arr2 = new BitArray(200);

arr1[2] = true;
arr2[2] = true;

if (arr1.And(arr2) == arr2)
   Console.WriteLine("good");
else 
   Console.WriteLine("bad");

It returns "bad" for some unknown reason.
My guess is that Equals implemented a reference comparison and not bitwise comparison.
It seems like a strange behavior as BitArray is classic for bitwise operations on it.

Am I missing something?

update: I've refactored Microsoft orginal BitArray and named it BitArray2. You can find it here.

   

Posted by Oren Ellenbogen 
16/01/2007 12:11, Israel time UTC-07:00,     Comments [2]  | 
# Tuesday, December 19, 2006

(Before you start - give a look at C# and XML Source Code Documentation)

So you build up a nice API that everyone can use but you want to provide nice, IntelliSense-enabled comments along with your magical code right?
Let's say I have the class Logger in my "Infrastructure" dll:

/// <summary>
/// Our logger....
/// </summary>
public class Logger
{
   /// <summary>
   /// Log the given message...
   /// </summary>
   /// <param name="messageToLog">The message to log.</param>
   public void Log(string messageToLog)
   {
   }
}

Now, my clients(e.g other teammates) want to use this logger. Adding a quick "File Reference" to the dll and they are good to go. This is great _but_ they also want to see the comments I provided as they type (IntelliSense in action baby). Surprisingly enough, they will _not_ see it "by default":

NoCommentOnLogger.gif

As you can see (well, not see, but that's my case) - we don't see the class comment "Our logger...". The same goes for our Log method:

NoCommentOnLogMethod.gif

Where are my comments ?!!?

Well, it turns out that you should make a small change to make it alright. Say hello to "XML Documentation file". Open the Project Properties, under the "Build" tab there is a little checkbox named "XML Documentation file" - make sure it's checked and you're done!
All you have to do is to recompile the dll and add the reference again (e.g remove & add, Dumb, but works) or manually copy the generated xml file to your bin directory (if CopyLocal = true).

CommentOnLogger.gif     

CommentOnLogMethod.gif

 

Conclusions:

You should always make sure that "XML Documentation file" is checked!
Why providing comments if no one can see them (unless you have access to the code and you make a "Project Reference").

I'm not sure why Microsoft made this checkbox unchecked as default.
Am I missing something here?

   

Posted by Oren Ellenbogen 
19/12/2006 02:07, Israel time UTC-07:00,     Comments [2]  | 
# Wednesday, October 04, 2006

A few days ago a teammate asked to me to help him with a little some-some. This some-some was an event delegation problem (some-some sounds better) that she wanted to implement and wasn't really sure how. The scenario is quite simple, we have a few classes and one of the classes is a little “deep” (deep object graph), meaning:

object of type A 
object of type B 
object of type C 
   inner member of type class D 
     inner member of type class E
      inner member of type class F – known as f1

Now, the value f1 can change, and while it does so, we need to notify the rest of the instances (a1,b1,c1,d1,e1) of that change and provide them some extra details about the change itself. One solution is to add an event to all the classes, register from each one to the inner member event and then f1 can trigger the change to E which will trigger the event to D and then to C->B->A. In short - delegate the call all the way up and around. It seems like a hard job to me - too many places to change, too many events to declare which are not really necessary. I came up with a static Events Notifier solution. Think of it as a repository for registering and triggering events. Here it goes:

public static class EventsNotifier
{
   public static event EventHandler<Status> StatusChanged = delegate {};

   public static TriggerChangeStatus(object sender, Status s)
   {
      StatusChanged(sender, s);
   }
}

Now each class, in its constructor, can register to EventsNotifier.ChangeStatus event and my f1 can call EventsNotifier.TriggerChangeStatus(this, new Status(...)); which will notify the rest of the objects. I know, it's not a perfect solution, but It has its pros. What would you do ?

   

Posted by Oren Ellenbogen 
04/10/2006 09:42, Israel time UTC-07:00,     Comments [3]  | 
# Thursday, September 21, 2006

COM object think that they understand .Net assemblies (via Proxy(tlb file)) but in matter of fact, this proxy is a mediator(girlfriend\gay-friend) to the real assembly that actually make the connection work while .Net assemblies think that they understand COM object, again, via proxy(Interop file) but in matter of fact, this proxy is only a mediator(friend, lesbian-friend) that make the connection work.

The hard migrating process my team encounters this days(and will keep dealing with for the next few iterations) makes you(well, me, but a sorrow shared is a fool's comfort) appreciate one-platform systems. Integration between different platforms can be a female dog (translation: bitch!) if you are not familiar with the tips&tricks on the subject. Working with the registry is a complete disaster. I don't think that the initial idea of MS was to abuse the registry so much and literally write every reference as a long GUID that points to some class\interface\dll. Hack, register a simple dll (via RegSvr32.exe) and unregister it can leave you garbage on the registry, not mentioning migrating VB6 code into VB.NET\C# code which requires RegAsm.exe for "old" clients. So much garbage to cleanup. And you think that throwing the garbage at your home, once every your-wife-is-nagging-again is hard. Think again.

Yes, they(COM, .Net) know how to communicate and live together, but just like Men and Women - you can't really understand how it actually works.

I wonder if I should start writing a book on the topic...

p.s - don't get me wrong, women are hard to understand but it's only making the game more fun. So does the migration challange.

.NET | @ff Topic | COM
   

Posted by Oren Ellenbogen 
21/09/2006 08:26, Israel time UTC-07:00,     Comments [4]  | 
# 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-07: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-07:00,     Comments [0]  | 
# Tuesday, September 12, 2006

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-07: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-07: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-07: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-07:00,     Comments [0]  | 
# Wednesday, August 16, 2006

This (very)little beauty is getting along quite nicely. I'm going to work quite a bit on it in the following days so keep tracking...

source:

Lnbogen.SeeCompass_v0.2.zip (205.34 KB)

.NET | TDD
   

Posted by Oren Ellenbogen 
16/08/2006 12:08, Israel time UTC-07:00,     Comments [0]  | 
# Friday, August 11, 2006

After sitting with Roy during our last meeting, we managed to write some neat tests and code and the SEE(Simple Expression Engine) infrastructure started to crystallized. Roy even managed to refactor the name of my infrastructure and brought a brilliant suffix - SeeCompass. SEE is like a compass that helps you navigate in the ocean of data; man, I think that the web-bully will not be happy with this phrase.

If you don't remember what is SeeCompass all about read this post.

Source:

Lnbogen.SeeCompass.zip (156.39 KB)

How to start:

1. Open the solution (I know, revolutionary).
2. Open Lnbogen.SeeCompass.Framework.Tests project.
3. Open the file FilterExpressionTests.cs under FilterExpression directory.
4. Jump to the test Build_EmptyFilter_EmptyString (remember the method name structure: MethodToTest_MethodState_ExpectedResult).
5. Move on to the next test, one at a time.


I know, it can be a little hard to grasp the "entire picture" at the moment, but the tests should give you a good pick at the future.
As always, I left one failing test which will lead to a very drastic refactoring (BetweenExpression should have more than one parameter) - this will give me an entry point to continue.

.NET | TDD
   

Posted by Oren Ellenbogen 
11/08/2006 05:59, Israel time UTC-07:00,     Comments [0]  | 
# Sunday, July 16, 2006

This is another brilliant idea from Juval Lowy. I got to see him speak about unify ASP.NET and WinForms security models last week and during the session (which was really great by the way, but that's for another day), I've notice this genius row:

public event EventHandler<EventArgs> Click = delegate {};

Isn't it a beauty ?!

I know, it doesn't ring a bell yet, so I'll make the picture a bit clearer. But before we move forward, let's take a few steps backward.

Starting from scratch, a reminder:

We want to raise our Click event.
I'm sure you are familiar with these lines:

private void OnClick(EventArgs e)
{
   if (this.Click != null) // check if the invocation list is empty
      this.Click(this, e);
}

The reason we do it is we we don't want to raise an event with an empty invocation list; This will raise an exception, which is a big no-no if we can avoid it. simple ah ?

This implementation is problematic as between the check (if statement) and the activation the listener can be removed. A quick fix will look like this:

private void OnClick(EventArgs e)
{
   EventHandler<EventArgs> handler = this.Click;
   if (handler != null) // check if the invocation list is empty
      handler(this, e);
}


Ok, so it's a little safer invocation now (I remember a version with locking, but the above will do for now).

Rewind:

Now let's get back to Juval's genius line I've showed before:

public event EventHandler<EventArgs> Click = delegate {};

attaching delegate{} to the invocation list will create (behind the scene) a class, with a random name, with an empty method (matching EventHandler<EventArgs> signature), with a random name.

Why is this so brilliant ? Because now we verified that the the event invocation list is
always filled with *at least* one (empty)listener.

We can't clear the empty listener as we don't have it's instance (it was generated for us) nor it's name.

The checks for not-empty invocation list can be thrown to the garbage. We now have a safe event, guaranteed.

This is certainly a best practice for working with events (following Framework Design Guidelines structure):

   Do   Consider attaching an empty delegate to your event.


Recap

public class MyClass
{
    public event EventHandler Click = delegate {};
    
    private void OnClick(EventArgs e)
    {
        // no need to check if (this.Click!=null)
        this.Click(this, e);
    }
}

nice and easy.


Extra: one more step for safe events:

If we're talking about safe events, there is an advanced scenario in which you want the "eat" exception raised by one of the listeners, so the the other listeners will still be triggered. In the above, any exception in one of our listeners will stop the triggering of our invocation list.

The solution is quite simple also:

private void OnClick(EventArgs e)
{
   EventHandler<EventArgs> handler = this.Click;
   if(handler != null)
   {
      Delegate[] list = handler.GetInvocationList();

      foreach (Delegate del in list)
      {
         try
         {
            EventHandler<EventArgs> listener = (EventHandler<EventArgs>)del;

            listener(this, e);
         }
         catch { }
      }
   }
}

Juval even wrote a cool generic utility class named EventsHelper which you can get here.

Brilliant.

.NET | Design
   

Posted by Oren Ellenbogen 
16/07/2006 10:13, Israel time UTC-07:00,     Comments [6]  | 
# Thursday, July 13, 2006

ORM conversations flood the web during the last months.

Microsoft new players (DLinq, ADO.NET entity framework) cause a lot of drama and "oh-ha" statements in our industry. Microsoft is playing around; They are throwing names all over the place (DLinq, LINQ for Sql, LINQ for simple scenarios, ADO.NET vNext, ADO.NET Entities, ADO.NET 3.0). I guess that the picture will become clearer in a few months as the minds behind this infrastructures will assemble and a new, solid infrastructure will take place. Just look at Remoting, WebSercies, Enterprise Services which assembled together into WCF.

This causes some old, damn good, questions to arise as well:

"Should I use Business Entities (Entity Info+ BL + DAL in the same class) or should I create a separate classes ?"

"Should I write my queries or ORM is good enough? I heard it's somewhat slow, but I'm not sure..."

"Should I use ORM and map my entities with attributes or with xml? What is better ?"

"Which infrastructure to use? Is DLinq or ADO.Net solid ? Should I use NHibernate? "

etc...

I'm not going to answer these questions at the moment, but I'm certainly going to address them in the following months as my BL->DAL agenda started to shift from separate classes to Business Entities. I'm still doing a lot of prototypes to see the pros & cons.

In case you are interested to know the difference between DLinq and ADO.NET Entities (or ADO.NET vNext, you name it), here is a nice post to set your mind.


Oh, before I forget - It is time to make some good names to Microsoft products !
Why not calling ADO.NET vNext something like DARVIN (Data Access Revolutionary INfrastructure) ?
That's cool !


Any thoughts ? names ?

   

Posted by Oren Ellenbogen 
13/07/2006 12:04, Israel time UTC-07:00,     Comments [0]  | 
# Wednesday, June 28, 2006

I don't know, maybe I'm missing something or maybe I'm just stupid (you can pick, just let me know):

class User
{
   public static readonly int ID; // class property

   public int ID; // instance property
}


Compiling this little cutie returns the error:
" The type 'ConsoleApplication1.User' already contains a definition for 'ID' "

What's going on here ? This properties are completely different, one is *instance* property and the other is *class* property. What is the conflict here? Am I missing some Microsoft spec on this one? Am I missing some OOP lesson? Is it C# restriction? Is it CLI restriction ?

I'm confused...

   

Posted by Oren Ellenbogen 
28/06/2006 10:02, Israel time UTC-07:00,     Comments [4]  | 
# Thursday, June 22, 2006

Prologue:

I'm a big fan of Interface with a Base Class which implement that interface with base behavior. Providing this two together allows the programmer to decide if he wants to inherit from the Base Class and override only the things he really wants or to implement the Interface from scratch.

Here is an example from our code:

1). The Interface:

public interface IPersistentEntity
{
   string ToXml();
   string GetKey();
   // ... snippet ...
}

2). The Base Class that implements the interface:

/// <summary>
/// Base class for a Business Entity.
/// </summary>
public abstract class EntityBase : IPersistentEntity
{
   public string GetKey()
   {
      return GetKeyCore();   
   }

   protected abstract string GetKeyCore();

   public virtual string ToXml()
   {
      // Build the xml via Reflection over the current type.
   }

   // ... snippet ...
}


I constraint my EntityCollection object to EntityBase:

/// <summary>
/// Represents a strongly typed list of Business Entities.
/// </summary>
/// <typeparam name="ENT">Entity type which inherits from EntityBase class.</typeparam>
[Serializable]
public class EntityCollection<ENT> : List<ENT>, ISerializable
   where ENT : EntityBase
{
   // ... snippet ...
}

As you can tell, I'm constraining the ENT generic type to be any object that inherit from EntityBase.


The Story:


My teammate, Moran (Yes, him again, goshh... he really challenges me to think deeply about our infrastructure), wanted to create a new EntityCollection of ISpecificEntity (i.e: EntityCollection<ISpecificEntity>). That means that he wanted to extend the IPersistantEntity I showed above.

The problem was that my EntityCollection made a constraint on the generic type to inherit from EntityBase.

That means that the interface should inherit from EntityBase class which is obviously not possible. so his interface should have been some sort of another SpecificEntity class that inherit from EntityBase. Well, that's no good as some of our existing entities already inherit from the EntityBase and Moran wanted to use them in the collection. That means that Moran should have change the signature of this class (among others):

public class Zone : SpecificEntity //EntityBase
{
   // ... snippet ...
}

The problem was that Zone was inherited also by another class and we couldn't change that. To make a long story short, our  headaches were a result of one simple fact:
One of the biggest drawback of inheriting from a Base Class is [your answer here].
You right, the biggest drawback is that you can do it only *once*.

Using abstract classes with interfaces behind is a very good practice, in my book anyway, but using it(abstract class) as a constraint in a Generic Type can cause you some problems later on. The only thing we did was to change the signature of EntityCollection to:

public class EntityCollection<ENT> : List<ENT>, ISerializable
   where ENT : IPersistentEntity
{
   // ...
}

That made our life easier as we can always implement additional interface(s) in our class.

Epilogue:

The drawback of single inheritance from class is a dangerous pitfall you should avoid while working with Generics constraints, so my tip for you is:

Constraint your generic type(s) by Interface and not by Base Class.

.NET | Design
   

Posted by Oren Ellenbogen 
22/06/2006 10:57, Israel time UTC-07:00,     Comments [3]  | 
# Monday, June 12, 2006

I'm proud to introduce "Filter By Expressions". As I mentioned in my previous post about LINQ and IQueryable<T>, I got several ideas about implementing some sort of data(base) filter mechanism just until LINQ will be stable enough. I have  3 alternatives: (1) Implementing some sort of HQL language (like NHibernate) or query parser, (2) use an existing infrastructure and (3) Implement my own mechanism. Considering the options with my managers' hat on, options (1) and (2) are irrelevant at this stage as the learning curve and the adjustments I'll have to make is simply too much for me at the moment. In addition, LINQ will be here shortly so I don't want to invest more than 2 days of work. This leaves me with option (3).

After some good thinking(nothing more) during the weekend and 15 minutes of exchanging ideas with Moran, the [1]API took form. Here is a quick example (from one of our .aspx files):

IFilterObject filter = new Filter();
filter.PageResults = true;
filter.CurrentPage = 1;
filter.PageSize = 10;

// Here is the gold !
filter.Where(
   Expression.EqualTo(Order.Field.PurchaseDate, DateTime.Today),
   Expression.Operator(OperatorType.And),
   Expression.EqualTo(Order.Field.IsValid, true)
);

ordersGrid.DataSource = OrdersGateway.Instance.Get(filter);


Any idea what kind of "Where clause" it will generate behind the scenes ?
I bet you do so here it goes(SqlServer syntax):

WHERE Orders.PurchaseDate = @p0 AND Orders.IsValid = @p1

@p0 and @p1 will be filled with DateTime.Today and true respectively.


Here is another example, this time with "Inner condition":

filter.Where(
   Expression.Block(
      Expression.GreaterThan(User.Field.Age, 18),
      Expression.Operator(OperatorType.And),
      Expression.NotEqualTo(User.Field.Email, "")
   )

   Expression.Operator(OperatorType.Or),
   Expression.EqualTo(User.Field.IsGoldMember, true)
);

This will generate the following query(SqlServer syntax):

WHERE (Users.Age>@p0 AND Users.Email != @p1) Or Users.IsGoldMember = @p2

@p0, @p1 and @p2 will be 18, "" and true respectively.

But what about complex scenarios ? My answer is "keep it simple". With this in mind I think that we covered about 98% of every-day queries, which is good enough for me at the moment.

At the moment, our Query Generator Engine only filter the Where clause so you can't do some sort of magic like LINQ or other infrastructures out there allow you to do. Still, this infrastructure is small enough to be easily integrated with almost any existing infrastructure and yet powerful enough to be extremely useful.

Oh, by the way - at current stage, our engine support queries for SqlServer & Oracle databases.

Enough about high-level API. I'll try to explain the Architecture before I'll start showing you the way I decided to sew this engine. Our first (static)class is Expression, which is kind of Factory for expressions:

Expression.gif

Factory of expression ah ? what kind of concrete objects I've got there ?
Well, here are few samples: EqualExpression, NotEqualExpression and OperatorExpression

Expressions.gif

IDataExpression inherit from IExpression and overload GenerateQuery method with two additional parameters: DatabaseMapper and IDataParameterCollection.

IDataExpression.gif

The former one(DatabaseMapper) will simply "tell" the Query Engine how to convert User.Field.Age enum into "Users.Age" string and the latter(IDataParameterCollection) will be an empty collection of parameters which every expression can fill according to its' needs.

Eventually, we've got an Engine that receives the IExpression(s) and generates code from them:

ExpressionEngine.gif

Here is the implementation of IQueryCreatorEngine.GenerateWhereClause():

string IQueryCreatorEngine.GenerateWhereClause(IExpression[] expressions, IDataParameterCollection parameters)
{
   IDataExpression wrapper = (IDataExpression)Expression.Block(expressions);
   return wrapper.GenerateQuery(this.Mapper, parameters);
}

Pretty straight forward: wrap the expressions with DataBlockExpression and let him take care of our business. Let's look at our DataBlockExpression.GenerateQuery method:

protected override string GenerateQueryCore(DatabaseMapper mapper, System.Data.IDataParameterCollection parameters)
{
   StringBuilder whereClause = new StringBuilder(this.Expressions.Length * 150);

   whereClause.Append("( ");

   foreach (IExpression exp in this.Expressions)
   {
      IDataExpression dataExpression = exp as IDataExpression;

      if (dataExpression != null)
         whereClause.Append(dataExpression.GenerateQuery(mapper, parameters));
      else
         whereClause.Append(exp.GenerateQuery());
   }

   whereClause.Append(" )");

   return whereClause.ToString();
}


The only thing we have to do now is to supply some sort of method which implement DatabaseMapper (delegate) signature when we initialize the QueryCreatorEngine. Here is a quick example:

QueryCreatorEngine engine = new QueryCreatorEngine(
   delegate(object field)
   {
       User.Field typedObj = field as User.Field;
       if (typedObj != null)
       {
          switch(typedObj)
          {
              case User.Field.Age: return "Users.Age";
              case User.Field.IsGoldMember: return "Users.IsGoldMember";
              case User.Field.Email: return "Users.Email";
              default
               throw new ArgumentException("field not supprted"); //whatever
          }
       }
       else
           throw new 
               ArgumentException("field != User.Field type"); //whatever
   });

That's it.

Our mapper is generated by tool (our lovely Code-Agent) and our Filter By Expressions infrastructure is ready to go !

If you are still here, leave me a comment and I'll send you a T-Shirt of "Code don't make me sleepy!".

I'll upload our Data Access infrastructure in a few days so be patient and let me know if this post made you happy.


[1] We did a quick API exam in our department and the results were good.

   

Posted by Oren Ellenbogen 
12/06/2006 01:22, Israel time UTC-07:00,     Comments [4]  | 
# 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-07: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-07:00,     Comments [5]  | 
# 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-07:00,     Comments [1]  | 
# Monday, May 22, 2006

I want to elaborate on my main ideas from my presentation about Code Templating - abstracting your code via delegates & anonymous methods. During the presentation, I talked about solutions to repetitive, every-day tasks. One of the examples I presented was something *we are all familiar with and that is querying our database. Lets take a look shall we?

public static List<User> GetUsersList()
{
   using (SqlConnection conn = new SqlConnection(ConnectionString))
   {
      SqlCommand cmd = new SqlCommand("Select Id, Name From Users", conn);

      conn.Open();

      List<User> users = new List<User>();

      SqlDataReader r = cmd.ExecuteReader();
      while (r.Read())
      {
         User u = new User();
         u.Id = Convert.ToInt32(r["Id"]);
         u.Name = Convert.ToString(r["Name"]);

         users.Add(u);
      }

      return users;
   }
}

Now let's imagine that we also have Get*List for Products, Orders, Items and Sales. That's 5 Get*List methods already. Let's look at the code that is common among those potential methods (in red):

public static List<User> GetUsersList()
{
   using (SqlConnection conn = new SqlConnection(ConnectionString))
   {

      SqlCommand cmd = new SqlCommand("Select Id, Name From Users", conn);

      conn.Open();

      List<User> users = new List<User>();

      SqlDataReader r = cmd.ExecuteReader();
      while (r.Read())
      {
         User u = new User();
         u.Id = Convert.ToInt32(r["Id"]);
         u.Name = Convert.ToString(r["Name"]);

         users.Add(u);
      }

      return users;
   }
}


So the first solution to refactor those lines of (repetitive)code out will be, obviously, via OOP.
Here is a quick solution I came up with just to make the point clear:

interface IDataReaderParser<TRet>
{
   TRet Parse(IDataReader liveReader);
}

static class DbServices
{
   public static TRet ExecuteReader<TRet>(
      IDbCommand cmd, 
      IDataReaderParser<TRet> parser)
   {
      using (SqlConnection conn = new SqlConnection(ConnectionString))
      {
         cmd.Connection = conn;

         conn.Open();

         IDataReader reader = cmd.ExecuteReader();

         return parser.Parse(reader);
      }
   }
}

So far we have some "parser" interface which will get a liveReader and return some generic type based on the required parsing. I don't know if you've noticed but DbServices.ExecuteReader holds all the lines I marked with red just before. 

Let's look at our GetUsers parser:

class GetUserListParser : IDataReaderParser<List<User>>
{
   public List<User> Parse(IDataReader liveReader)
   {
      List<User> users = new List<User>();

      while (liveReader.Read())
      {
         User u = new User();
         u.Id = Convert.ToInt32(r["Id"]);
         u.Name = Convert.ToString(r["Name"]);

         users.Add(u);
      }

      return users;
   }
}

Our parser get the live IDataReader and returns a list of users. Simple.
GetUsersListParser.Parse method contains the rest of the code (all code minus code in red) from our original GetUsersList method.

Finally, our GetUsersList method looks like this:

public static List<User> GetUsersList()
{
   SqlCommand cmd = new SqlCommand("Select Id, Name From Users");

   GetUserListParser parser = new GetUserListParser();

   return DbServices.ExecuteReader<List<User>>(cmd, parser);
}

That's nice, but is it good enough ?? 
For every Get*List method we will have to build a separate class which will implement IDataReaderParser<TRet>. Let's pause here.

* breath.... good .... *


Let's rewind. When I started writing the original GetUsersList method, my main goal were those lines:

// (1) Create command
SqlCommand cmd = new SqlCommand("Select Id, Name From Users");

// (2) In some magical way, execute the command and return a live reader so I can parse it into objects.
List<User> users = new List<User>();

while (liveReader.Read())
{
   User u = new User();
   u.Id = Convert.ToInt32(r["Id"]);
   u.Name = Convert.ToString(r["Name"]);

   users.Add(u);
}

return users;


Open a connection against the database, executing the command as reader and disposing the connection were irrelevant at the time, I knew that I will have to write those lines down but they were just means to get to my real goal(=my real code). So I refactored my code via some sort of OOP solution.

Now I have pieces of code all over the place and even worse - in 1-2 months from now I will have to "Go To Definition" just to remember what the hack is GetUsersListParser class.


My main code was refactored out of my method.


Life shouldn't be so hard. Like a very wise(and old, they are always old) programmer once said: "If you code it, it will come;".
Let's look at a different solution - let's abstract our code via delegates & anonymous methods.

So our DbServices.ExecuteReader<TRet> will look like:

public delegate TRet ReaderHandler<TRet>(IDataReader liveReader);


static class DbServices
{
   public static TRet ExecuteReader<TRet>(
      IDbCommand cmd, 
      ReaderHandler<TRet> handler)
   {
      using (SqlConnection conn = new SqlConnection(ConnectionString))
      {
         cmd.Connection = conn;

         conn.Open();

         IDataReader reader = cmd.ExecuteReader();

         return handler(reader);
      }
   }
}

DbServices.ExecuteReader receive a (Sql)command to execute and an "handler" - a method with the same signature as ReaderHandler<TRet> delegate. ExecuteReader method will execute the command as a reader and send it(the reader) to the method handler. So who is this "handler" I talk about so much ?! The anonymous method !!

Let's look at the new version of GetUsersList:

public static List<User> GetUsersList()
{
   SqlCommand cmd = new SqlCommand("Select Id, Name From Users");

   return DbServices.ExecuteReader<List<User>>(cmd,
      delegate(IDataReader liveReader) <-- our handler, inline
      {
         List<User> users = new List<User>();

         while (liveReader.Read())
         {
            User u = new User();
            u.Id = Convert.ToInt32(liveReader["Id"]);
            u.Name = Convert.ToString(liveReader["Name"]);

            users.Add(u);
         }

         return users;
   });
}


The entire logic is just in front of me now, no need to start smelling around it !

Just like in the first OOP solution, I don't need to handle the connection, call the ADO.NETs' ExecuteReader, nothing.

To sum up:

Delegates & anonymous methods       1 : 0       OOP



Think about solutions you've implemented via OOP and start thinking about delegates as an alternative abstraction technique. For many straight forward architectural problems, delegates will be by far a better solution than traditional OOP.

My next post on this matter will cover the expected question - when delegates solution is too complex??

* Well, most of us anyway. For the rest of you - be cool and play along.

.NET | Design
   

Posted by Oren Ellenbogen 
22/05/2006 07:21, Israel time UTC-07:00,     Comments [1]  | 
# Friday, May 19, 2006

In the new asp.net 2.0 web application model, every web page (.aspx) and it's code behind (the class that this page "Inherits" from, actually it's partial with it, but that's the property name) compiles into a single assembly. At least as a default behavior.

aspnet2_Compile_flow.gif

 

That means that the following relationship is completely valid in this compilation model:

Default.aspx (CodeFile=Default.aspx.cs, Inherits=MyNamesapce.MyDefaultPage)
   Default.aspx.cs (class name MyNamespace.MyDefaultPage)

Default2.aspx (CodeFile=Default2.aspx.cs, Inherits=MyNamesapce.MyDefaultPage) // Inherits: same as above
   Default2.aspx.cs (class name MyNamespace.MyDefaultPage// class name: same as above


This can be quite confusing though. While you're developing everything will work as expected as every .aspx & aspx.cs will compile to a different assembly so no collision will occur; So you think you're good to go...

The problems start to show up when you're trying to compile everything to a single assembly (production env.). Now you'll get an "aspnet_merge.exe" error which tells you that you can't combine (1) Default.aspx with (2) Default2.aspx and (3) MyNamespace.MyDefaultPage class. It makes sense, after all, those three are partial classes.

When can this happen ?

if you Copy-Paste an existing page & forget to change the name of the class in the CodeBehind and in the Inherits property.

Solution - How to check if you're really good to go:

I've written a small utility with Mario, my teammate, which will find this duplication and give you a little report telling ya if you have more than 1 aspx file which inherit from the same class. Running it on the example above will produce the following report:

aspnet2_inspector_util.gif

Now all I have to do is change the Default.aspx.cs class name and change the Inherits property name in Default.aspx.

How to use the "Duplication Inspector" utility ?

(1) Extract the zip file (down below).
(2) Open app.config and change the "WebDirectoryToInspect" as needed.
(3) Run the InheritsDuplicationInspector.exe and voila !

You can find the source files here:

InheritsDuplicationInspector.zip - 47 KB

Have fun.

   

Posted by Oren Ellenbogen 
19/05/2006 09:55, Israel time UTC-07:00,     Comments [1]  | 
# Thursday, May 18, 2006

I had so much fun lecturing yesterday before the C++/C# User Group about abstracting your code via delegates & anonymous methods. The number of people that showed up was really astonishing, at least to my expectations, as about 70 people gave me the honor to talk about something I really like so thank you guys !

I got some really good feedbacks(update: Royo, Ken and Shani dedicated a post on the matter) from the audience, one of them even told me at the end that my lecture was much better than one of the lectures at TechEd 2006 about Generics so I'm really happy that my words and demos made an *impact*. Still, I feel that I can do a lot better so I hope I'll have the pleasure to give more lectures on the near future.

Finally, I got to say a BIG thanks to a bunch of folks: Justin Angel helped me to put my lecture on video so all of you (Hebrew speakers) can hear & see the live presentation(Justin - you rock!), Roy Osherove helped me think about the context of my lecture and connected me to the C++\C# User Group Leaders - Shai & Moshe. I owe a big thanks for Shai Bar Lev & Moshe Raab for giving me the opportunity and making it all possible. And finally, I want to say thanks to my teammates at SQLink that really pushed me through.

You can download the presentation & demos from this links:

Code Templating presentation (ppt) - 1.8 MB

Code Templating Demos (zip) - 500 KB

Code Templating Database (zip) - 139 KB

    * You need to restore this database on Sql Server 2005 Express which comes free 
       with VS.NET 2005. Without the database the ISPARefactoring demos wouldn't work.


The video will be available in a few days so stay tuned.

btw - Barca won the Champions League cup! What a great evening!

Barca.gif

   

Posted by Oren Ellenbogen 
18/05/2006 12:50, Israel time UTC-07:00,     Comments [3]  | 
# Sunday, May 14, 2006

Preface:

Let's say that you have Button control named myBtn and you want to handle its Click event:

myBtn.Click += new EventHandler(myBtn_Click);

static void myBtn_Click(object sender, EventArgs e) {
   // do something
}


Now, raise your hand if you ever attached the event handler to the event manually, meaning you wrote "new EventHandler(myBtn_Click);" or even specified the method signature "void myBtn_Click(object sender, EventArgs e)".
I don't know about you, but the way I work is by simply writing "myBtn.Click +=" and this magic yellow thingi appears:

autoCompleteEvent.gif

TAB-ing again will generate the method stub and I'm good to go.

Doing this yellow magic on delegates parameters:

We all(?) worked with List<T>. This nice class has some nice methods like ForEach, FindAll, Find etc which get delegate(Action<T>\Predicate<T>) as parameter. for example: 

List<int> numbers = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });

// Print the numbers via ForEach method
numbers.ForEach(
delegate(int i) {
   
Console.Write(i);
});

Would it be great if you can write something like:

numbers.ForEach(

And the yellow thingi will popup and by clicking TAB this code will be generated:

numbers.ForEach(delegate(int i) {
   //TODO
});

This means that this IDE feature should check the type of the delegate - the number and type (even generic type!) of parameters and the return type. This will prevent us from looking at MSDN or "Go To Definition" while working with delegates which are sent as parameters.

Time for you to make a difference:

what say you ? can this save you some time ? If so - leave a comment, I'll do my best to implement it or to forward this request to MS folks (as ladybug).

   

Posted by Oren Ellenbogen 
14/05/2006 12:27, Israel time UTC-07:00,     Comments [5]  | 
# Monday, May 08, 2006

In the previous version of asp.net, v1.1, the CustomValidator did NOT run when the control(e.g TextBox) was empty. Possible solutions were to create your own control (something like RequiredCustomValidator : CustomValidator) or the change WebUIValidation.js file so it will actually validate the control even if it's empty. Now, in the new version, v2.0, you can simply set the ValidateEmptyText to true and you're done. Nice (and useful) !

   

Posted by Oren Ellenbogen 
08/05/2006 04:02, Israel time UTC-07:00,     Comments [2]  | 
# Friday, May 05, 2006

The using keyword works on objects that implement IDisposable interface (an interface with one member, the Dispose() method).
So a code like this:

using (SqlConnection conn = new SqlConnection("connection_string"))
{
    // use conn...
}

Is actually transformed into:

SqlConnection conn = null;
try
{
    conn = new SqlConnection("connection_string");
}
finally
{
    if (conn!=null)
        conn.Dispose();
}

The using keyword allows more elegant writing, nothing more actually.

The additional feature I would like to see is that in case of exception, a method in the implementor of IDisposable will be called, meaning the code should(?) be transformed into something like this:

SqlConnection conn = null;
try
{
    conn = new SqlConnection("connection_string");
}
catch(Exception err) // *
{
    HandleException(err);
}
finally
{
    if (conn!=null)
        conn.Dispose();
}


Of course, I would have to implement HandleException(Exception e) method as part of implementing IDisposable interface.

Why is this good for ??

Well, think about creating a transaction scope interface:

interface ITransactionScope : IDisposable
{
    void Commit();
    void Rollback();
    // ....
}

In this scenario, it would be great that if no exceptions were thrown, the transaction should Commit() by default,
but if any exception was thrown and not handled - do Rollback().

using (ITransactionScope trans = DbServices.StartTransactionScope())
{

    // delete 1

} // should do Commit()


using (ITransactionScope trans = DbServices.StartTransactionScope())
{
    
    // delete 1
    
    throw new ArgumentException("just to make the point clear");

} // should do Rollback()


HandleException(Exception e) will allow me to set a flag for Rollback on Dispose or to Rollback immediately; This can be quite handy.

Today I Rollback at the Dispose(if the transaction state is "uncommitted") and I force my programmers to call Commit() method directly.

* I know that catching Exception is a bad practice by default, but in those scenarios I would rather ask the "is\as" question(s) and handle my exception than wrapping using with try-catch blocks. After all, using should allow elegant code...

What do you think ?

update:
I've posted a ladybug at Microsoft Product Feedback, you can check it out (and vote!!!) here:

http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=f3c7e216-8790-4937-acc0-502848232a9d

   

Posted by Oren Ellenbogen 
05/05/2006 10:37, Israel time UTC-07:00,     Comments [2]  | 
# Tuesday, May 02, 2006

My team use the Sql Server 2005 Replication feature in order to synchronize between databases in different enviornments. One of the strange things though, is that the reference to Microsoft.SqlServer.Replication generated a weird "Invalid access to memory location. (Exception from HRESULT: 0x800703E6)" Error. After a quick google search I found this link which offers a nice workaround (this seems to be VS.NET 2005 bug) which worked for several folks out there but unfortunately it didn't work for me. The search continues...

   

Posted by Oren Ellenbogen 
02/05/2006 09:32, Israel time UTC-07:00,     Comments [4]  | 
# 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]  | 
# 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

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]  | 
# 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-07: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-07: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-07: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-07: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-07:00,     Comments [1]  | 
# Wednesday, January 18, 2006

Do I need to call base.METHOD after overriding it, and if so - when is it the right time ?


Well, I'm glad you've asked; I had some chat with my co-worker about the subject when he did some overriding to the Form (WinForm) methods and he wasn't sure about when is it smart to call the base method and if so, should he call base.METHOD before implementing his code, or maybe after. To clarify, quick example:

public class MyForm : Form
{
   protected override void OnLoad(EventArgs e)
   {
      //OK, what here ???!!

      // Custom code here ?
      //base.OnLoad(e); // should I ?
      // Or maybe - Custom code here... ?

   }

}

After thinking for a few seconds, I came up with this explanation - sort of my "best practice" to the issue:

When do I call base.METHOD:

  1. If you don't know the implementation in the method you've just override: assume that it does some "magic" stuff which is important to the correct flow of the application; But This doesn't mean that you must call the base method.
    • If you want to stop the logic flow, it makes sense to override the appropriate method and write your code which will change the flow according to your need. In this scenario there is no need to call the base method.
    • If you don't want to change the logic flow, or you're not sure - call the base method.
  2. If you know the implementation in the method you've just override: no "magic" stuff so this is an easy call - if you need the code in the base method, call it - otherwise - leave it out.

Do I call base.METHOD after my custom code, or maybe before:

This is a tricky one and there is not straight answer - my way of thinking and tackling this question is simply by Explore, Run & Learn "process" - meaning, try to Explore about the base method original purpose and try to figure out the logic; This will give you some logical direction whether you need to call the base method or not. For example - if you override the Render method, you can tell (by MSDN or by Reflector) that its rendering the entire object graph so you probably should call it (eventually). Now that you have some feeling about whether you need to write your code before or after the base.METHOD call, Run it and exam the results:

  • Does the page behaves as you expected?
  • Can you mess it up so it won't work in some scenarios - how can you deal with it ?
  • Grab the nearest programmer available, can he think about something which will mess it up ? if so - how can you deal with it ?

According to the results and the answers about the given questions, you should now have a clear vision about your decision. Make the required adjustments, place some important remarks(to describe your thinking at the moment) and feel good about your code, you did your best to get a good result. And most important - Learn from the process so it will be more natural on the next time you'll have to face this decision.

   

Posted by Oren Ellenbogen 
18/01/2006 08:08, Israel time UTC-07:00,     Comments [5]  | 
# Saturday, January 14, 2006

I love the new generics in .Net 2.0; Combining it with abstract classes and I could almost throw my interfaces to the garbage collection of life (coming soon...).
There is one scenario though that I can't seem to figure out the solution with a generic type, and that's the is keyword. The problem is that you can't ask the object if it is from GenericClass<T> type, assuming you don't care about the T object. You can't even ask if it is from GenericClass<BaseClass> (where T : BaseClass) in case that T is inherits from BaseClass. The only way to get "true" from this phrase it is to ask for the specific T used in the GenericClass, which is most of the time unknown. I know, I know, this is Chinese at the first read, so here is an example and than you'll have to go Memento(the movie) on this post and roll back to the beginning of the post to understand my point:

public class EntityCollection<T> : List<T>
   where T : EntityBase
{
   public virtual string GetXml()
   {
      StringBuilder output = new StringBuilder(Count * 100);

      output.Append("<" + typeof(T).Name + "List" + ">"); 

      // Build the inner xml for every "T" object.
      this.ForEach(delegate(T t) { output.Append(t.GetXml()); });

      output.Append("</" + typeof(T).Name + "List" + ">"); 

      return output.ToString();
   }
}

public abstract class EntityBase
{
   public virtual string GetXml()
   {
      StringBuilder output = new StringBuilder(100);
      Type currentType = this.GetType();

      output.Append("<" + currentType.Name + ">");

      // --
      // Use reflection to build the properties xml on the fly.
      PropertyInfo[] props = currentType.GetProperties();
      foreach (PropertyInfo prop in props)
      {
         object propertyValue = prop.GetValue(this, null);
         string text = "";
         if (propertyValue != null)
         {
            // ****
            // DON'T WORK:
            // propertyValue will never be from EntityCollection<EntityBase> though it will contain EntityCollection<Item>
            // and Item inherits from EntityBase. This is logically right of course, BUT I still need a workaround.
            if (propertyValue is EntityCollection<EntityBase>) // <-- The problem is here!
            {
               text = ((EntityCollection<EntityBase>)propertyValue).GetXml();
            }
            else if (propertyValue is EntityBase)
            {
               text = ((EntityBase)propertyValue).GetXml();
            }
            else
            {
               text = "<![CDATA[" + propertyValue.ToString() + "]]>";
            }
            // ****
         }

         output.Append("<" + prop.Name + ">");
         output.Append(text);
         output.Append("</" + prop.Name + ">");
      }
      // --

      output.Append("</" + currentType.Name + ">");

      return output.ToString();
   }
}

public class Order : EntityBase
{
   private int m_orderID;
   private EntityCollection<Item> m_orderItems;

   public Order(int orderID)
   {
      m_orderID = orderID;
      m_orderItems = new EntityCollection<Item>();
   }

   public EntityCollection<Item> OrderItems
   {
      get { return m_orderItems; }
      set { m_orderItems = value; }
   }
}

public class Item : EntityBase
{
   private int m_id;
   private string m_name;

   public int ID
   { 
      get { return m_id; }
      set { m_id = value; }
   }

   public string Name
   {
      get { return m_name; }
      set { m_name = value; }
   }

   public Item(int id, string name)
   {
      m_id = id;
      m_name = name;
   }    
}

And here is a simple tester:

static void Main(string[] args)
{
   Order o = new Order(1);
   o.OrderItems.Add(new Item(1, ".Net 2.0 book"));
   o.OrderItems.Add(new Item(2, "yet another .Net 2.0 book"));

   string oXml = o.GetXml();
}


The only solution I found to this problem is to implement an interface and inherit from it in my generic class and than use the is keyword on my interface instead of on the GenericClass<T>, i.e:

  1. Create IXml interface which hold the GetXml method signature.
  2. The EntityBase & EntityCollection class implement the IXml interface.
  3. The EntityBase.Getxml() method check if propertyValue is IXml and if so - call ((IXml)propertyValue).GetXml();
   

Posted by Oren Ellenbogen 
14/01/2006 03:15, Israel time UTC-07:00,     Comments [0]  | 

After talking with some folks about it, I did some refactoring to the structure.

Just to remind you my purpose:

  1. I want to validate the data before sending it to the DB(performance stuff), or at least at some level:
    • For "string" fields - check for their length (by DB definition).
    • For not nullable fields - check that they aren't null, depending on the required action (Insert, Update, Delete)
I don't want to go all the way to my DB just to get the errors "ID column can't be null" nor "Name field must be less or equal to 50 chars".

The actions I took:

In the ideal world, the entity would know how to validate it self, from A to Z, but the problem is that the validations change according to the required action(Insert, Delete, Update) and I don't want to couple my entity with my DAL.
I decided to split the "validation" checking in two - some of it in my Entities layer and the other some, in my Data-Access layer.

  1. Entities layer:
    • In every set of the property(if the property is from string type, of course) -> validate the length of the property.
  2. Data-Access layer:
    • Insert action:
      • Check that all the not nullable fields aren't nullable, unless the column is an Identity(auto-increment) field.
    • Update action:
      • If the field has to be updated (its status is "dirty", meaning, the programmer wants to update it) -> check for his "null condition" (all rights for this phrase are reserved for me, Oren Ellenbogen Inc.).
      • Check that all the primary key columns are not null.
    • Delete action:
      • Check that all the primary key columns are not null.
Any thoughts ?
   

Posted by Oren Ellenbogen 
14/01/2006 01:52, Israel time UTC-07:00,     Comments [4]  | 
# Friday, January 13, 2006

I like to handle my .cst(CodeSmith templates files) files with my VS.NET for it's integration with Visual Source Safe.
Well, no need for VSTweaks in this version of Visual Studio, The trick is quite simple:

  1. Open you Visual Studio .Net 2005.
  2. Tools -> Options -> Text Editor -> File Extension
  3. In the "Extension" text-box write ".cst" and in the "Editor" drop-down-list select "Html Editor".
This will put some color to your .cst files.
Sweet.
   

Posted by Oren Ellenbogen 
13/01/2006 12:27, Israel time UTC-07:00,     Comments [0]  | 
# Friday, January 06, 2006

I'm doing some major refactoring to our code and I'm still wondering about the "right" way to do some of the things. This post will reflect my thoughts about implementing our "Entities" layer. Just to be clear, in my world, "Entity" is an object that represents a single row in a given table or some sort of logic being.
My entities looks something like:
 
 
1). I have entity "base" class:

public abstract class EntityBase
{
   protected StringBuilder m_validationErrors;

   public string ValidationErrors
   {
      get
      {
         return m_validationErrors.ToString();
      }
   }

   public bool IsValid(Enum field)
   {
      Validate(field);
      return (m_validationErrors.Length == 0);
   }

   protected abstract void Validate(Enum field);

   // Some other code...
}

This class will hold the "basic" behaviors for my entities.
 
2). I've cut aside some of my code from my real Area class, just to think about the implementation later:
 
public class Area : EntityBase
{
   [Flags]
   public enum Fields
   {
      ID = 0x01,
      Description = 0x02
   }

   public int? ID = null; // In the real class, it's not like this...
   public string Description = null; // In the real class, it's not like this...

   public bool IsValid(Fields field)
   {
      return base.IsValid(field);
   }
 
   //OREN NOTE: "problematic" code number (1) - I'm doing the type check on run-time.
   protected override void Validate(Enum field)
   {
      if (!(field is Fields))
         throw new ArgumentException(this.GetType().Name + ".Validate method must get Area.Fields as parameter");

      Fields f = (Fields)field;

      m_validationErrors = new StringBuilder(50);

      if (((f & Fields.ID) != 0) &&
         ID == null)
      {
         m_validationErrors.Append("ID property must be set." + Environment.NewLine);
      }

      if (((f & Fields.Description) != 0) &&
         Description == null)
      {
         m_validationErrors.Append("Description property must be set." + Environment.NewLine);
      }
   }
 
   // Some other code...
}
 
Here is a dirty usage of this Area class:

Area a = new Area();
//a.ID = 1;
//a.Description = "oren";
if (!a.IsValid(Area.Fields.ID | Area.Fields.Description))
   Console.WriteLine("Errors: " + a.ValidationErrors);
else
   Console.WriteLine("a is valid");

a.IsValid method is a "strongly typed" method which will get Area.Fields as parameter so I'm quite(not entirely, see problem (1)) happy. The catch is when I'm starting to work with multiple Area entities.

3). Declaring my generic EntityCollection class:

public class EntityCollection<ENT> : List<ENT>
   where ENT : EntityBase
{
   protected StringBuilder m_validationErrors;

   //OREN NOTE: "problematic" code number (2) - I want to get Area.Fields as parameter if I'm declaring EntityCollection<Area>
   public bool IsValid(Enum field)
   {
      m_validationErrors = new StringBuilder(Count * 50);

      int counter = 0;
      this.ForEach(delegate(ENT e)
      {
         if (!e.IsValid(field))
         {
            m_validationErrors.AppendFormat("Index in list: {0}.{2}Errors: {1}{2}",
               counter,
               e.ValidationErrors,
               Environment.NewLine);
         }

         counter++;
      });

      return (m_validationErrors.Length == 0);
   }

   public string ValidationErrors
   {
      get { return m_validationErrors.ToString(); }
   }
}

Here is a quick usage for this EntityCollection class:

EntityCollection<Area> areas = new EntityCollection<Area>();
Area a1 = new Area();
a1.ID = 5;
Area a2 = new Area();
a2.Description = "orennnnn";
Area a3 = new Area();
a3.ID = 1;
areas.Add(a1);
areas.Add(a2);
areas.Add(a3);

if (!areas.IsValid(Area.Fields.Description))
   Console.WriteLine("areas Errors: " + areas.ValidationErrors);
else
   Console.WriteLine("areas is valid");

areas.IsValid accept Enum as parameters, this is quite shitty because in my ideal world it would accept only Area.Fields as parameter.

The solution I found at the moment is to inherit from EntityCollection and add the check there, something like:

public class Areas : EntityCollection<Area>
{
   public bool IsValid(Area.Fields field)
   {
      m_validationErrors = new StringBuilder(Count * 50);

      int counter = 0;
      this.ForEach(delegate(Area a)
      {
         if (!a.IsValid(field))
         {
            m_validationErrors.AppendFormat("Index in list: {0}.{2}Errors: {1}{2}",
               counter,
               a.ValidationErrors,
               Environment.NewLine);
         }
   
         counter++;
      });

      return (m_validationErrors.Length == 0);
   }
}

I can always check the integrity of the collection via outside delegate & ForEach method, but I want the collection to verify its inner entities without my help. This is why I need your advice - what do YOU suggest in order to handle this more nicely ? Am I doing something totally wrong ?

   

Posted by Oren Ellenbogen 
06/01/2006 06:34, Israel time UTC-07:00,     Comments [0]  | 
# Tuesday, November 22, 2005

Well, Richard explains it better than me, so just read his post.

update: for some reason the link doesn't work well, so here is the full address:

http://blog.hundhausen.com/Database+Concordance+Generator+CodeSmith+Style.aspx

Just copy it and put it in the address bar, sorry for the inconvenience.

   

Posted by Oren Ellenbogen 
22/11/2005 05:00, Israel time UTC-07:00,     Comments [0]  | 
# Saturday, November 12, 2005

The title got me your attention right? good, because this task - unit testing our WebService in one of our project - seemed to be a frazzled mission at first, but it's amazing how good tools and healthy thinking able you to think about new ways to "assign" the redundant work to the one(and only) dude that never complains (though it makes noises here and there) - the computer !

Let me take a step back and explain a little bit about our WebService and the unit tests it was required:
We currently finished develop another application in our department and this application was required to expose an interface for "CRUD"ing(Create,Read,Update,Delete) several "System Tables"("cities","countries","languages" etc) in the application. Eran(my teammate) was assigned for the job and he did a great job by well designing a general (XML)protocols for "talking" with the WS and by implementing the WS itself. After building the WebService and manually testing it he told me that his work was done and he's ready for his code review. I still have the image burned in my mind about how happy he was thinking about the required protocols, learning about WSE 2.0 (for WS security), implementing the WS itself to be extendable and maintainable, that it was almost tragic to see his face after I've told him that we should write an extensive unit tests for this WS due to his importance and it's extensive usage by our 3rd party softwares. The WebService had 5 methods and it handled 18 tables in our application so I thought about testing 3 different cases for each method, for each table:

  1. 1 valid xml which should return the expected valid data from the WS.
  2. invalid structure xml which should return an error from the WS.
  3. 1 invalid data xml which should return an error from the WS.

The math was simple:

3 xml files * 5 methods * 18 tables = 270 unit tests !

Eran started to plan the following 2 months for this taks but I had something else in mind - let's generate those unit test and hack, while we're in the middle of it, let's generate the XMLs as well !

I started writing the templates(while Eran was looking and learning the required basics) via CodeSmith (did I mentioned that this tool rocks? I'm sure I did, but again - Eric, great job) and after 2 hours we had all the xml files generated. Eran continued the job and written the classes (which holds the unit test methods) and checked that everything integrated properly. After a total of about 6 hours we had 270 unit tests, but more important, we managed to avoid a lot of dirty work and in case we need to support a new table, the unit tests for it will be only 2 clicks job; This is quite extendable, doesn't it ?

   

Posted by Oren Ellenbogen 
12/11/2005 05:35, Israel time UTC-07:00,     Comments [2]  | 

Pasha sent me a great presentation about Identity 2.0, presented by Dick Hardt, which all of you presenters out there ought to see !

Even if you don't understand what's the presentation is all about, you must listen to the presenter and check his style - he's amazing speaker and a great performer.

Here it is:

http://www.identity20.com/media/OSCON2005/

   

Posted by Oren Ellenbogen 
12/11/2005 04:59, Israel time UTC-07:00,     Comments [1]  | 
# Friday, October 28, 2005

Yesterday the Israeli .NET architect group met at HP(Raanana) for a lecture about GAT and LINQ which was presented by Roy Osherove.

If you haven't heard about GAT & LINQ before, here is a (really) terse summary about them and my comments about the presentations:

  1. Guidance Automation Toolkit (aka GAT): this is Microsoft way to take a piece from the "automation" utilities cake. See, MS finally got the idea that there are too many folks out there using CodeSmith, O/R Mappers, RapTier etc; Now they're integrating a tool in the Visual Studio which will able us to automate everything directly through the studio itself. With GAT, you can build packages, or as I like to call them - "well defined and well presented(GUI) processes", to automate for example a build of an entity(\data) class based on a given table in the DB, just like you can do it today with 3rd party softwares. But you can do much more with this tool basically because it's so well integrated with the studio. Now, creating full controlled wizards straight out from the VS.NET which will able you to automate creating VS.NET solutions\projects\items is even easier than developing an Add-in for the VS.NET 2005. The main reason I don't think this will take off immediately is the GAT lack of easy configuration, but this will be fixed in the following year, and then, man, I think that the current Code Generators and O\R Mappers softwares will have to really take the next step and start running after MS (like we used to). Roy's presentation was nice, but I think he made a mistake by given us some general info & demos without really pointing the real deal - integration, integration, integration and Microsoft money & time = something we'll use later on, one way or another.
    Presentation TIP: IMHO, the first slide in every technical presentation should contain the phrase:
    "At the end of my presentation you will all know ____" or something like it.
    I would start with something like: "hey folks, we're going to talk about GAT, and before I'll begin, let me assure you, each and every one of you will use this tool one way or another, not tomorrow, but in the next 6-10 months so pay attention to MS new baby; Good, now that I have your attention, this tool is not quite ready for immediate use, and that's why I've told you 6-10 months, BUT, let me give you some general info about the new product and some demos, (after all, every presenter must challenge the "god of demos") and at the end of my presentation I promise you'll all understand the big step Microsoft did to ease our life's as architects. Please keep in mind that this is only a 1 hour presentation so I rather show you the big picture and the why-you-should-use-it instead of getting deeper into the code, does it sound right to you ? (everybody will node anyway)"
    After that said, I would concentrate more on the amazing integration with the VS.NET, the ability to use wizards to build wizards, the ability to control everything you need in the studio while using the studio itself rather than talking about the recipes\actions and "deep level" demos. If In 1 hour presentation you can't really teach me how to create a working Guidance Automation wizard, don't start to and stop in the middle after you see the material is to complex for such a short time limit, concentrate on the big picture and give me a list of links to read later on. The most important thing is to let the audience know the main goal of your lecture and what will they gain from it straight from the beginning, so at the end of it, they'll be really able to tell you if you did a good job.
  2. Language Integrated Query (aka LINQ): This is one of the coolest shit you'll ever see, I promise you that, but it will be released only with C# 3.0 so I won't elaborate much on it now and just say that this technology ables you to run queries on collection. I won't even give samples, there are plenty right here. This presentation by Roy was much better because it was clearly understood that the presentation will be focused on the new abilities LINQ will give us - pure "introduction" presentation (and to extract some "wowwww","aaahh", "hhooo" comments which is great to have in any presentation ;-)).

So, it was a nice meeting and I even got the chance to see some folks from the army I haven't seen for a lot of time (Effie, Gabi and the rest of the team) so I'm glad I went.

Oh, Two things before I'm out of here -

  1. I've registered to Microsoft Sql Server 2005 convention in November, will I see you there ?
  2. A very good friend of mine, Amir Markowitz, has turned 32 yesterday (sorry for the late post Markowitz!) so happy birthday dude !
OK, time for me to go, until next post.
   

Posted by Oren Ellenbogen 
28/10/2005 09:20, Israel time UTC-07:00,     Comments [4]  | 
# Thursday, October 20, 2005

This task can be a little tricky, so after messing with it's HTC (TabStrip.htc) here is how you do it:

To enable tab:

document.all.tags("TabStrip")[0].getTab(0).setAttribute("disabled", false);

To disable tab:

document.all.tags("TabStrip")[0].getTab(0).setAttribute("disabled", true);

* You can select other tabs of course or loop over them to disable\enable all of them at once (as needed).

Maybe it can save someone else the time I've wasted on it.

Back to code...

   

Posted by Oren Ellenbogen 
20/10/2005 08:55, Israel time UTC-07:00,     Comments [3]  | 
# Monday, October 10, 2005

Our team use Microsoft's Membership Management Component Prototype for our users management in our application. We've wanted to add "forgot my password" screen, and our new member in our team, Dror(pay his blog a visit) was assigned for the mission. While trying to configure the MemberRoles component (in the web.config) to allow password retrieval, we've got a strange "bug"(\behavior); When we've tried to write this code:

<add name="AspNetSqlProvider" type="Microsoft.ScalableHosting.Security.SqlMembershipProvider, MemberRole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7c773fb104e7562" connectionStringName="wsha" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" passwordFormat="Hashed" applicationName="test" description="Stores and retrieves membership data from the local Microsoft SQL Server database" />

We've got a strange error "Configuration Error" (with unknown exception and other "helpful" details), and to make it even stranger, if you set the enablePasswordRetrieval to false, everything works well. So, like always, the first thing I do after I smack the keyboard (It works on my TV at home, why not here ?), I googled for solution (and publish it here, for higher PR ;-)) BUT this time - NO LUCK, I didn't manage to find something helpful. I couldn't thought about a better solution than to look at the source via Lutz Reflector so I've opened the dll there and checked MemberShipConfigHandler.Create(..) method; There I saw that this method creates an instance of SqlMembershipProvider and call it's Initialize method with all the data from the web.config. There I found the answer:

if ((this.PasswordFormat == MembershipPasswordFormat.Hashed) && this.EnablePasswordRetrieval)
{
   throw new Exception("Configured settings are invalid: Hashed passwords can not be retrieved. 
       
Either set the password format to different type, or set supportsPasswordRetrieval to false.");
}

So, the error was that we've used passwordFormat="Hashed" instead of "Clear" or "Encrypted". Well, That's making a lot of sense because the "Hashed" algorithm is implemented via SHA1, which is one-way encryption so obviously I can't retrieve the user's original password.

The real problem(and that's why I've called this behavior a "bug") is that somewhere in the way, the original helpful exception was caught and replaced with a really bad exception which doesn't allow the programmer to understand what have he done wrong. This is a very good example of why it's so important to keep the exception stack with you all the way up.

Back to code...

   

Posted by Oren Ellenbogen 
10/10/2005 02:10, Israel time UTC-07:00,     Comments [0]  | 
# Wednesday, September 21, 2005

Remember my last post on this subject ?
Just to refresh your memory, I've come across a strange Visual Studio .NET (2003) + Visual Source Safe (6.0d) problem:
I got "The operation could not be completed" alert every time I've closed my solution. Man, It was frustrating, but I think I have a solution for it if you're using the same versioning mechanism I'm using and that is - "Link File" between your Class Libraries. It seems that the "Link File" option mess the solution\VSS\projects up for some unknown and undebuggalbe(is that a word? no ah..., well, it is now) reason.

The solution is quite simple, remove the linked file and put it in each of your class libraries. I know, I hate this solution too, but at least it will keep the sanity of your solution which is much more important than "1 place"(except asp.net 1.1 project, which don't support "Like File" option) version holder.

Now I'm "The operation could not be completed" FREE !

.NET | VSS
   

Posted by Oren Ellenbogen 
21/09/2005 02:39, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, September 18, 2005

I'm not a happy coder right now.
I gave Eran, a new gifted programmer in my department, a task:

I have a simple table in my database, named Users, with the fields ID (int, identity) and Name(varchar).
I want to send xml to a web-service which looks like this:
<User>
    <ID>1</ID>
    <Name>Oren</Name>
</User>

I want the web-service to add this row to the Users table in some magic way. I thought that by using Typed DataSet, which will use the table's schema, and loading the xml into it will do the trick, but I was wrong. We tried many things but they didn't seem to work.

The reason I want to use schema is to verify the given data(xml) structure before I insert it to the DB (and of course, without it how the DS(DataSet) will "know" to load it properly?). In addition, if tomorrow I need to add Password field to Users table, the only thing I'll have to do is to re-generate the Typed DataSet and set the password via the xml (<Password>mypassword</Password>).

The code looks like this:

string sXml = "<User><Id>1</Id><Name>Oren</Name></User>";
using (SqlDataAdapter adapter = new SqlDataAdapter("", connString))
{
    UsersDS ds = new UsersDS();

    System.IO.StringReader xmlSR = new System.IO.StringReader(sXml);

    ds.ReadXml(xmlSR, XmlReadMode.ReadSchema);
    ds.ReadXmlSchema(HttpContext.Current.Server.MapPath (".") + "\\UsersDS.xsd");

    adapter.Update(ds.Tables["Users"]);
}

For some reason my ds isn't getting filled.

Do you have any idea what am I doing wrong ?

btw - I know I can always parse the xml by myself and create the required commands, but I thought it will be a maintenance nightmare and less comfortable than letting the schema & the Typed DataSet doing the job for me.

Update [20.09.2005]:

Amir Markowitz, again, came to the rescue and with his help we've managed to solve this one:

using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Users", connString))
{
   SqlCommandBuilder scb = new SqlCommandBuilder (adapter) ;
   UsersDS ds = new UsersDS();
                    
   XmlTextReader reader = new XmlTextReader(new StringReader(sXml));

   ds.ReadXml(reader);
   ds.ReadXmlSchema(HttpContext.Current.Server.MapPath (".") + "\\UsersDS.xsd");

   adapter.Update(ds.Tables["Users"]);
}

Now, the xml data (in "sXml" variable) looks like this:

<UsersDS xmlns="http://tempuri.org/UsersDS.xsd">
    <Users>
        <UserName>Orenn</UserName>
        <Name>Oren E.</Name>
    </Users>
</UsersDS>

So thanks again Markowitz, I owe you one (again, add it to my list).

   

Posted by Oren Ellenbogen 
18/09/2005 07:06, Israel time UTC-07:00,     Comments [0]  | 
# Saturday, September 17, 2005

I'm responsible for an hybrid ASP-ASP.NET application with an ASP log-in screen; This screen authenticate the user and set a unique session value in case he's valid. All the other ASP screens check this unique session value and let the user stay in the system as long as it exists. The problem was that there were ASP.NET pages that I had to use this security mechanism in them, meaning to check the session in my .aspx files in the same pattern (same unique session) as the other .asp pages did. In order to do that I had to access the ASP session from my ASP.NET pages, which is impossible due to the simple fact that they DO NOT share the same "room" (teenagers problems, you know). The solution came after googling a little bit and testing the suggested solution on my application.

The pattern goes like this:

aspToaspnet.gif

Once again, I'm a happy camper.

   

Posted by Oren Ellenbogen 
17/09/2005 02:53, Israel time UTC-07:00,     Comments [0]  | 
# Tuesday, September 13, 2005

I've encounter a numerous bad usages of try, catch and throw statements in my last 3 years in .NET so I thought to write here my "best practices" in this subject.

Before I begin, just to remind you about the "using" keyword

" The using statement defines a scope at the end of which an object will be disposed. " (MSDN)

Meaning, this code:

using (MyDisposableObject o = new MyDisposableObject())
{
   // use o...
}

Is equal to:

MyDisposableObject o;
try
{
   o = new MyDisposableObject();
   // use o...
}
finally
{
   // Don't forget, MyDisposableObject must implement IDisposable
   o.Dispose();
}

The using statement is much more "cleaner" than the try-finally(->call Dispose) block. Of course, in order to use the using statement, MyDisposableObject must implement IDisposable interface, but most of the .NET frameworks' classes which use external resources do, so no problem here.

When do I use the using keyword instead of "try-catch(-finally)" ?

In any case your code block doesn't required any exception handling (catch) and you're using a disposable object.
 
When do I catch an exception ?
 
You should use the catch statement only if you can REALLY handle the exception - meaning you want\need to "eat"(catch it and do nothing about it) the exception or you (want to)\can try to "fix" the application's flow according the exception type (call transactionInstance.Rollback() in my data-access-layer if an error occurred, for example).
 
Do NOT catch exceptions as a "default" behavior in your code !
The following code is a BAD practice in exception handling:

try
{
   //some code
}
catch(Exception e)
{
   throw new Exception("X operation error: " + e.Message);
}
finally // if exists.
{
   //some code
}

Why is it bad ? The catch statement doesn't handling the original exception, it creates a (bad)new one which means:
  1. The Stack Trace of the original exception will be LOST, which means I lose the ability to view the entire "process" (who called to who flow).
  2. In the demonstrated code, I catch an exception and re-throwing a pointless new exception. Throwing exceptions is an expensive task so you should avoid (at any cost) throwing them as long as you don't really need to !
  3. If you wrap an exception, at least save the original exception in the InnerException property (I'll elaborate later on).
When do I wrap an exception, when do I rethrow it ?
  1. You should catch and wrap the exception with a new one only if you can add INFORMATIVE data to the original exception which WILL be used later on. Writing this type of code (in my DAL) will be a smart idea usually:

    SqlTransaction trans;
    SqlConnection conn = null;
    try
    {
        // use the connection to do some DB operation
        
        trans.Commit();
    }
    catch(Exception e)
    {
        if (trans != null)
            trans.Rollback();
        
        // Wrap the exception with DALException
        // I can check if e is SqlException and by the e.Number -
        // Set a "clean"(show to user) message to the DALException.
        // I can add the full "sql" exception in some custom property, 
        // I can determine which stored procedure went wrong, 
        // I can determine the line number (and so on).

        throw new DALException("clean message to the user", e);
    }
    finally
    {
        if ( conn != null && conn.State == ConnectionState.Open )
            conn.Close();
    }

    Why is this code smart ? Because I call the Rollback() in case of an error, which will ensure "clean" database. Because it "hides" the original SqlException which allows me, at my Business Layer, to catch a generic DALException which will abstract the Business Layer from the Data Access Layer. Because I CAN add more informative data to the exception so the Business Layer could send the GUI (to show the user).

  2. You should rethrow the exception if you catch-ed it but you "found out" that you can't really handle it:
    try
    {
        // do some code...
    }
    catch(Exception e)
    {
        if (e is SqlException)
        {
            // Add more information about the exception and
            // throw a new, more informative, exception:
            throw new DALException ("more data", e);
        }
        else
        {
            // I can't handle it really, so I'm not even going to try
            throw; // <-- look at this syntax ! I'll explain later on
        }    
    }
     
    Calling throw; will bubble the original exception (including its' Stack Trace) - this will actually "cancel" the catch statement.
When you wrap an exception, you should *almost* always use the "InnerException" property
 
When you wrap an exception, you should save the original exception as InnerException:

try
{
}
catch(Exception e)
{
   throw new MyCustomException("custom data", e);

   // OR

   MyCustomException mce = new MyCustomException("custom data");
   mce.InnerException = e;
}

This will preserve the original stack which will be important for later debugging.

 

Any Insights you want to share with me ?

   

Posted by Oren Ellenbogen 
13/09/2005 11:16, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, September 04, 2005

Hey y'all,

I can't seem to stop, those add-ins bastards are too addictive !
Oh well, here are more great VS.NET add-ins you should all check them out:

  1. GhostDoc - This great utility will able you to "auto" document your methods\properties with a single mouse click.
  2. WhidbeyCommands 2 - Just read the man's post :) TIP: if you give presentations while using the VS.NET, you MUST download this baby (check out "Demo font" option) !
  3. HandleWhiteSpace - Clean your files from unnecessary white spaces.
peace.
   

Posted by Oren Ellenbogen 
04/09/2005 09:08, Israel time UTC-07:00,     Comments [5]  | 
# Saturday, September 03, 2005

It's possible to use built in keywords in order to mark some lines in you code for later reference. For example, I use the "TODO" keyword as a remark over a set of lines I know I'll have to change later on -

todos.gif

As you can see, my TODO task is now appearing at my Visual Studio .Net "Task list" which is great for a constant reminder.
As default, the Task list shows only the "Build Errors" so in order to support other keywords you'll have to (mouse)right-click over one of the table headers ("Description" for example) -> Show Tasks -> All (or any other suitable option). In addition, you can select how to sort the results by (I use "Priority").

* If you want to change the custom tasks priority or names - go into Tools-> Options... -> Environment -> Task List.

   

Posted by Oren Ellenbogen 
03/09/2005 11:13, Israel time UTC-07:00,     Comments [0]  | 
# Saturday, August 20, 2005

Read this post by the legendary Brad Abrams and watch the videos you're interested at. I've seen "Designing Inheritance Hierarchies" and "Enabling Development Tools" videos (for the moment) and I promise that you can learn a thing or two as well ;-).

Happy learning...

update:
I thought it will be interesting to write my notes from the Designing Inheritance Hierarchies video, so here it is:

  1. Interfaces don't allow backward compatibility ! Let's assume we have to following interface

          public interface IMyInterface
          {
               void MyMethod();
          }

    Now let's assume that I have MyClass which inherits from IMyInterface. If I'll decide to add a new 
    signature to the interface, MyClass will be broken (TypeLoadException will be thrown in compile time).

  2. Base Classes version better than interfaces - if MyClass was inherited from MyBaseClass instead of IMyInterface I wouldn't have a problem to add new signatures to the class without causing the inherited classes to break.
  3. If you must inherit from 2 "root" classes, the recommended pattern is:

          public class A {}
          public class B {}
        
          public class C : A // Let's assume that A is "more" root to C than B
          {
             public B BInstance
             {
                get
                {
                    // return B class instance.
                }
             }
          }

  4. You can use Interfaces in "private" way via Explicit declaration:

      public interface IMyInterface
      {
         string ReturnSomething();
      }

      public class MyClass : IMyInterface
      {
          string IMyInterface.ReturnSomething()
          {
            return "oren";
          }
      }

      Now, when you create a new instance of MyClass, you won't see 
          ReturnSomething method on the public view:

      MyClass.gif

      Though, you can always call this method simply by casting c to IMyInterface:

      MyClassViaCasting.gif

      This can be useful if you want to "hide" some of the interfaces' abilities in your 
          class. This is recommendable if you don't want the "clients" to use a 
          certain behavior directly
through the class. 
         .NET framework use this ability in Int32 structure:

      int i = 5;
      i.ToString() // work
      i.ToInt32(); // don't work.
      ((IConvertible)i).ToInt32(); // work !

      " This member supports the .NET Framework infrastructure and 
        is not intended to be used directly from your code. " 
      (from MSDN, Int32.IConvertible.ToInt32 method)

 

I hope I've managed to give you some insights, just enough to convince you to start viewing these videos.

   

Posted by Oren Ellenbogen 
20/08/2005 06:21, Israel time UTC-07:00,     Comments [0]  | 

I'm currently using a .resx file at my projects to contain my friendly client's messages. I'm reading from this file via ResourceManager class which allows me to supply consistent messages at my GUI layer, e.g for every successful delete in my application you'll get the same message format "The {0} was deleted successfully" - in my "Workers" form you'll see The worker was deleted successfully and in my "Cars" form you'll see The car was deleted successfully;

I've encounter the SR (String Resource) Generator a week ago and I thought to give it a try. So, what is SR generator ?

" This custom tool allows the generation of a resource class (and optionally .resx file) from either a .resx file, or the Microsoft SR.strings file. "

I think that a simple example will show the tool's capabilities.

  1. I've downloaded the source which also includes the .msi file and installed it.
  2. I've added a file named SR.strings to my web application:

             SRGSolutionOnAdd.gif

  3. I've used the "Custom Tool" option and call SRCodeGen - this is an EXE which will parse your .strings file.
             SRGFileProperties.gif
     
  4. Next I've edit the SR.strings file -       

      [strings]
      Worker = Worker
      ItemDeleted(string itemName) = The {0} was deleted successfully.
      ItemAdded(int itemId, string itemName) = The {1} was added successfully, it's new ID is: {0}.

      [strings.he]
      Worker = עובד
      ItemDeleted(string itemName) = ה{0} נמחק בהצלחה.
      ItemAdded(int itemId, string itemName) = ה{1} נוסף בהצלחה, מספרו החדש {0}.

  5. I've saved the file in UTF-8 format, for Hebrew support.
             SRGFileEncoding.gif
     
  6. Rebuild the web project, this will cause the SRCodeGen to generate required files:
  7.                   SRGGeneratedFiles.gif
  8. Now lets use the SR class which was generated for us, here is my usage of it 
  9.          PageMessage.Text = SR.ItemDeleted(SR.Worker); // In my Worker.Delete()
     
             OR
             
             PageMessage.Text = SR.ItemAdded(newId, SR.Worker); // In my Worker.Add()
     
  10. Finally we can select the SR.Culture we want to use, so the messages will be formated in the correct language. This can be done easily be calling:
                  SR.Culture = new System.Globalization.CultureInfo("he");
   
                  OR
 
                  SR.Culture = new System.Globalization.CultureInfo("en");

         You can put this code in your Global.asax.cs in Application_Start method or 
         change it at any time, according to your needs.

 

This tool is a MUST in my opinion for two main reasons:

  1. IntelliSense, IntelliSense, IntelliSense ! (don't you love it ?!?!).
  2. Changing the messages Culture requires only one line of code, simple as that.
   

Posted by Oren Ellenbogen 
20/08/2005 01:10, Israel time UTC-07:00,     Comments [0]  | 
# Friday, August 19, 2005

If you're trying to postback from a modal dialog window, you'll see that a new window will open up with the results. In order to stay at the same window, use <base> element inside the document's <head> element -

<html>
   <head>
      ....
      <base target="_self"/>
   </head>
   ....
</html>

   

Posted by Oren Ellenbogen 
19/08/2005 08:39, Israel time UTC-07:00,     Comments [1]  | 

As you aware by now, I'm kind of programming-gadgets freak. After sharing with you the magic of SlickRun I thought it will be nice (of you to listen, I'm gonna write it anyway) to recommend about another two tools.

  • Visual XPath - After reading Justin's recommendation about it I thought to give it a try. In my every day work I'm handling a lot of xml, mostly via XmlHttp or sophisticated client side-work (like dependable DropDownLists, custom validations, building dynamic html) and this tool just give you great ability to test XPath phrases with no effort and nice GUI (always important). 
 
  • VSTabs - My second recommended tool is actually an add-in for Visual Studio .NET; The greatest value of this add-in IMHO is the file wrapping tab. It "smart" enough to wrap your .aspx file with it's .cs file and put them all in one tab. Well, one image is better than 1000 words so -
 
          vstabs.gif
   
        As you can see, it's wrapping all the linked files in one tab which is great if like to be organized,
        or you're one of those fellows, like me, that sometimes getting lost if I have
        MyFile.aspx at the beginning of the tabs scrollbar and MyFile.aspx.cs at the end if it.
 
If you have some add-ins to share with me - bring it on !
   

Posted by Oren Ellenbogen 
19/08/2005 07:24, Israel time UTC-07:00,     Comments [1]  | 
# Friday, August 12, 2005

Hey happy coders,
 
I'm currently developing a "2-weeks-max" application for an Israeli bank (If you see "Israeli bank" instead of the name of the bank, you don't have sufficient privileges ;-)). The characterization was written and approved on the fly, without a deep understanding of the client's domain, i.e what are the other applications that the users use in his every day work ? are they look the same ? does he "MUST" have some features that his already used to in his other applications ?
Now I'm facing the harsh results.
 
I'll give you an example of "little-MUST-feature-that-can-come-back-and-bite-you". The user requested a screen which will have to following fields in it (and some others, but they're irrelevant now):
  1. Requester drop down list: show all the users from a specific group in the AD (active directory).
  2. A->B->C linked drop down list: 3  DDL (drop down list) which are connected meaning that when you select a different value in A DDL all the values in B&C DDLs must show all the children of A (changing B will change C values of course).
This looks like a trivial requests right? Well, you're right, if you look at this skeleton request it may appear trivial, but the key is to understand how to user expect to choose a value from those DDLs. In my case, the user likes to work with auto-complete drop down lists. Combining his auto-complete mechanism in this screen was NOT a trivial task at all. The client gave me his code, so it seems that I just have to integrate it in my code and Voila; BUT The code was written for ASP, so I had to wrap it in a custom web control, handle the viewstate of the control, and worst - his code didn't worked so well (client-side behavior) so I was required to adjust and fix it as well(black box component in my a$$).
 
The 2 weeks application is now estimated in 3 weeks, 50% more than the first estimation !
I'm expecting a good night 24:00-06:00 sleep at the office for the next 2 weeks, wish me luck !
 
Some lessons I've learned:
  1. Don't give a fast reply for hours estimation just to move along and get the development process running, it WILL hurt you later on.
  2. Always try to understand the solution domain as well as the client's domain. Ask him to show you other applications that he uses for his every day work, ask him if he wants the same GUI in his new application that you're going to develop for him. If he does, think about the amount of time you'll be needed in order to do that, do you need to use a specific "template" so the new application will look the same as his old ones (how are you going to integrate it with ease?), do you need to allow him some special features that his already used to (auto-complete drop down list)? do you need to support key combination (Ctrl+S will save his document) ? In a "clean"(without technical considerations) characterization it probably will not be shown, but you must consider it in the technical characterization(if you have one) and in your total hours estimation ! Don't forget that the user thinks that adding a new feature to the application is an easy task because he already saw those features in other applications he uses every day ("can't you simply copy it from here???") - you must remind him that it's not a trivial task, and allow him to choose if he wants to spend time on these features.
  3. "Milk" the client for information, write all the possible scenarios that the client expect the system to handle. What screen X will show when I login as Administrator, what it will show when I login as Technician, as Supervisor ? Don't start programming unless you have the answers for those client "trivial" scenarios, refactoring will be a bitch !
  4. update: just to clarify, I didn't write the characterization and neither was my PM (project manager), it was written by another co-worker a long time ago. This is a huge mistake IMHO, you must ask the implementors, if you're not one of them, for their opinion on the development process before you can give your hours estimation.
Any tips you can share with me ?
 
 
   

Posted by Oren Ellenbogen 
12/08/2005 01:20, Israel time UTC-07:00,     Comments [4]  | 
# Wednesday, August 03, 2005

I saw a post in one of the forums I'm active at about "how to insert multiple rows to a table in the database".
The main goal in this scenario, and that's a rule of thumb in almost any database-operation, is to send a bulk of requests so they'll be send for execution in ONE roundtrip to the database.
 
I immediately thought to concatenate the insert requests via ";"(or using the "Bulk Insert" command) for Sql Server or using "BEGIN" + "END" for Oracle.
 
[SqlServer]
SqlConnection conn = new SqlConnection("your-connection-string");
string query = "insert into t1 ('value'); insert into t1 ('value2');";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.ExecuteNonQuery();
 
[Oracle]
OracleConnection conn = new SqlConnection("your-connection-string");
string query = "BEGIN insert into t1 ('value'); insert into t1 ('value2'); END;";
OracleCommand cmd = new OracleCommand(query, conn);
cmd.ExecuteNonQuery();
 
Someone from the forum suggested that all we need to do is to create the required commands object (with the query inside) and wrap them with a transaction. His code looked like this:

using (SqlConnection oCon = new SqlConnection("ConnectionString"))
{
   oCon.Open();
   IDbTransaction transaction = oCon.BeginTransaction();

   try
   {
         string Commands[] = new string[] {"insert...", "insert..."};
         foreach (string sqlCommand in Commands)
         {
            SqlCommand oCom = new SqlCommand(sqlCommand, oCon, transaction);
            oCom.ExecuteNonQuery();
         }

         transaction.Commit();
   }
   catch
   {
      transaction.Rollback();
   }
}

He claimed that the transaction object will simply collect the commands and only in transaction.Commit(); the request will be sent to the DB so only one roundtrip was performed.
Well, it didn't sound right to me, I knew that the transaction wraps the commands but I thought that every call to ExecuteNonQuery() will cause a roundtrip to the DB. But I wasn't absolutely sure so I've decided to check it out and I've built a simple tester:

// I've created Cities table (Sql Server) with the fields -
// 1. ID - int - PK & identity
// 2. Name - varchar(50) - Unique !
using (SqlConnection oCon = new SqlConnection("connString"))
{
   oCon.Open();
   SqlTransaction transaction = oCon.BeginTransaction();

   SqlCommand c1 = new SqlCommand("Insert into cities(name)values('oren_test1')", oCon, transaction);
   SqlCommand c2 = new SqlCommand("Insert into cities(name)values('oren_test1')", oCon, transaction); // this will throw an exception for duplicated row (Cities.Name is unique)
   SqlCommand[] commands = new SqlCommand[] {c1, c2};

   try
   {
      foreach (SqlCommand command in commands)
      {
         command.ExecuteNonQuery();
      }

      transaction.Commit();
   }
   catch(Exception err)
   {
      Console.WriteLine("error: {0}, rollback.", err.Message);

      transaction.Rollback(); 
   }
}//using will close the connection even in case of exception.

As you can see for yourself(try it), the second ExecuteNonQuery (for the second insert) throw me an exception about the duplicated row (unique exception) so now I'm sure that the roundtrips are NOT "saved" by wrapping the command with a transaction. It's making a lot of sense, the DB opens a transaction while calling the BeginTransaction() method and keeping it open until we call the Commit() or Rollback() methods. In between, while calling the ExecuteNonQuery() method, the database saves the row in a temporary table just until the the transaction ends (again, via Commit() or Rollback()) and only then the rows are inserted to the "real" table (i.e Cities table).

Conclusion

One of your main concerns while developing a web application is to prevent redundant roundtrips from your application server to the database server.

While the transaction object is vital for data integrity while inserting\updating\deleting many(more than 1) rows and it can boost your request(Trying to insert 1000 rows to the table, each insert with it's own private transaction, will be much slower than calling the same insert with one transaction for the all 1000 rows), it doesn't mean that it's wrapping your calls to the DB and saves those redundant roundtrips.

And if I wasn't clear so far - You should use the first approach showed in this post.

p.s -
General tip: (need I to say?) Always check your theories before you running along and using them in your applications.

   

Posted by Oren Ellenbogen 
03/08/2005 08:25, Israel time UTC-07:00,     Comments [2]  | 
# Saturday, July 30, 2005

Why do we(my bad, I) need code generator ?
I really don't want to get into this philosophical argument, whether code generation is good or not, but just think of your Code Generator as a silent programmer which REALLY loves to do your dirty repetitive work. Please read the following with an open mind to the subject, you've got nothing to lose.
 
Background
Way back, When I was still serving my country, I was "introduced" to the world of Code Generation. The concept was well familiar to me, but I didn't saw a tangible implementation until my team leader at the time, Pavel Bitz, showed us his(great) implementation which later on became the first code generator (aka "CG") I ever used. This CG was written in PL/SQL and ran, obviously, on our Oracle (9i) database. I wasn't so happy about the extendability of this code, but we were in a tremendous stress to develop & deploy our projects so there was no time to develop something "cleaner"(in my opinion anyway). After few weeks, at my final days in the army, I was starting to build my own code generator just to understand more of the .NET framework power - i.e usage of templates, custom config files, Database reverse-engineering, reflection, practicing my OOD\OOP etc. After all, nothing teaches you better to "exploit" the framework than writing an application which will test its capabilities. After 2 weeks I had a nice CG which ran quite well and did everything the PL/SQL CG did and then some.
My time at the army was done and I was back in the free market.

2 days after I was employed for SQLink company, I talked with Amir Engel about the idea of code generation. He told me that he managed to write some templates with CodeSmith and he showed them to me. It looked great but I was hoping to use my CG for that purpose, still, I wanted to protect my "baby". But this desire was gone when I read about CodeSmith's SchemaExplorer. My god, I was shocked about how easy it is to write a template which will connect to my database with zero (0 !) effort. In addition, it has its own Studio which allows me to write,test and debug my templates with ease.
BUT the biggest advantage was that there were many open source templates out there - just for me to use !
 
Code Generation - safety first
Before you start to generate code, you must think about how to integrate the code generation usage in your every day work without the need to overwrite your "custom" writing. I'll give you an example - Let's say that we generate the Data Access Object for Users table in our database. This object does the CRUD (Create\Insert, Read, Update, Delete) operations for that table. Now I need to add a "specific" method named "GetUsersFromCity" which will return all the users from a given city id. So I'll add the method to my UsersDAL class and I'm an happy programmer no ?   (think here...)  NO!
Why not ? because the next time I'll want to generate this class again, because one of the fields in the table was changed or a new field was added to the table (whatever), I don't want to overwrite the class and lose my custom changes !
The "Base" principle:
This is where the "Base" principle kicks in and help us to protect our custom changes. My correct "DAL" object class structure will be:

// File: UsersDALBase.cs
public class UsersDALBase
{
    // our "generated" code here - all the CRUD operations for example.
}

// in another file!
// File: UsersDAL.cs
public class UsersDAL : UsersDALBase
{
    // My custom behivors here.
}

Every time I'll regenerate the code, I'll overwrite the "Base" file and no harm done - my custom changes are safe !
In my "upper" layers, I always use UsersDAL(or [table]DAL for that manner) and not UsersDALBase.

Now that we've got the background, it's time to introduce to you my amigo -

CodeSmith - harness its power for your own need

I'm not going to write here about how to use CodeSmith, there is too much information about this issue all over the web - just google a little and I'm sure you'll do just fine. What I'm going to talked about is what's the greatness of CodeSmith and my tips about easy development and debugging while using this tool.
 
  • SchemaExplorer - Stop doing all the reverse engineering for Oracle\SqlServer (via "system tables"), it's already written for you. The only thing you need is to specify is the connection string and... thats it ! You want to see how easy it is? OK OK, relax:

      <%@ CodeTemplate Language="C#" TargetLanguage="C#"
        Src="../OeCodeTemplate.cs" Inherits="OrenEllenbogen.Templates.OeCodeTemplate"
        Debug="False" Description="Generate an entity class for a given table." %>

      <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" 
         Category="Connection" Description="Table Object should be based on." %>

      <%@ Assembly Name="SchemaExplorer" %>
      <%@ Import Namespace="SchemaExplorer" %>

      <%
      // Collection of all columns in the table.
      ColumnSchemaCollection Columns = new ColumnSchemaCollection(SourceTable.Columns); 
      %>

      <% 
      // Variables by table columns.
      for (int i=0; i < Columns.Count; i++) { %>
      /// <summary>
      /// <%=Columns[i].Name%><%=(Columns[i].Description.Length>0) ? " : " + Columns[i].Description : ""%>
      /// </summary>
      protected <%= GetCSType(Columns[i]) %> <%=VariableStyle(Columns[i].Name)%> = <%= GetCSDefaultByType(Columns[i]) %>;
      <% 
      } //end for 
      %>

         Some Explaining:
    • you can use "code behind" file (*.cs) which holds the common methods for all your templates files (mine is OeCodeTemplate.cs)
    • I use the methods GetCSType, VariableStyle and GetCSDefaultByType methods which are in my "code behind" file, but this are simple methods which you can copy\write by yourself.
         As you can see, it's so easy to start dealing with the template itself instead of trying to remember 
         how to get all the indexes\columns\primary keys\(etc)  from a given table.
  • Templates GUI - You've seen that I'm using SourceTable property on the previous section, the great thing about it is when I'll open this template with CodeSmith explorer I'll be able to pick the table directly from my DataSource. So easy and comfortable.
   CodeSmithExplorer.JPG   
 
 
  • Huge community - you can find a lot of examples in CodeSmith forums. Don't try to write something which was already written before you; You can always find a template and get some of its code for your specific need.
  • Its easy - believe me, my 4 years old cousin can write a template with CodeSmith, its that easy !
  • Its(was) free ! - version 2.6 is free for use, but the new one (3.0) costs (nothing you can't afford though).
Developing with CodeSmith
  • Using Lut'z reflector with CodeSmith 2.6 - The main problem with this version (and former) is the lack of IntelliSense. This is a problem due to the simple fact that you can't remember every method\member  in SchemaExplorer object for example which makes it harder for you to develop. The simple solution is to use the reflector over the SchemaExplorer.dll, which "sits" in CodeSmith directory, and explore your way to the required member\method.
  • Debugging - Debugging with CodeSmith 2.6 (and former)  isn't so comfortable, but it doable - that's enough for me. In order to do it, all you need to do is to put Debug="True" in the page header directive and call Debugger.Break(); before the lines you want to debug.

NOTE: in the new version (3.0), Eric .J. Smith, the creator of this great tool, spoiled us with brand new features like built-in IntelliSense and easier debugging options and much more.


Summarize:
Code generation, in my humble opinion, is MONEY SAVER, simple as that, you can cut down the development time by half !
I've built full-spectrum templates for my N-Tier applications - Entities (object which represent table), Data Access objects, Business Object, Web forms, Utilities layer, Cache layer and stored procedures script generator. I'm now able to build 50%-60% of the project "foundation" before I need to write my first code line ! In addition,  I'm using my CodeSmith templates for my every day work - I did some helper templates like generating new "SqlParameter" with the parameter type\size\scale according to the column type, This is great for adding a new SqlParameter to SqlCommand with "full information" about the parameter in single click.
And finally, I'm not afraid to change the database because I know what I need to change and now - it's even EASY to do.

 

   

Posted by Oren Ellenbogen 
30/07/2005 10:16, Israel time UTC-07:00,     Comments [0]  | 

As I've promised - I share with you my experience with NAnt while attempting to automate my build process for my ASP.NET project. After reading a lot on the subject, I must admit that the documentation is quite poor and the "open source" examples are not exactly what I'm looking for. Before I'll start, if you don't know what is NAnt or NAnt contrib, now will be a good time to do some reading, I'll wait...

Requirements (What do you need to install before you can start):

  1. Download and install NAnt.
  2. Add the nant\bin directory path to your PATH variable ("System Variables").
  3. Download and install NAnt contrib.
  4. Integrate between NAnt and NAnt contrib using these steps:
    1. Copy nant-contrib\bin\*.dll to nant\bin\ directory.
    2. Create the folder nant\bin\tasks\net (manually).
    3. Copy nant-contrib\bin\*.dll to nant\bin\taks\net directory.
  5. Download NAnt.UtilityTasks.dll and put it in nant\bin directory.

Let's Start:

OK, now we're ready to start the build process; So here is my solution structure:

MySolution
   - WebProject (ASP.NET project)
      - *AssemblyInfo.cs
      - Other files and directories (& porno, of course)
   - BusinessLayer (Class Library)
   - DataAccessLayer (Class Library)
   - EntitiesLayer (Class Library)
   - *SolutionInfo.cs
  - etc..

* Before I continue about the process itself, I must mention that I'm using "Link File" option in order to share my AssemblyVersion attribute in my ClassLibraries projects. In a perfect world, ASP.NET projects would be able to "Link File" as well, but (surprisingly) it's not; So I have 2 places which hold the AssemblyVersion:
1. MySolution\SolutionInfo.cs (This file is being linked in all of my class libraries).
2. MySolution\WebProject\AssemblyInfo.cs.

Great, we can carry on -
I've discussed about the proper build process with my friends A&A (The Amir's aka "The markowitz" and "The Engel") and we've agreed that we require 2 processes - "Build"(complete new version) and "Rebuild"(rebuild the current version, it's required after the Build process failed for some reason).

The desired processes work flow
:
Note: you don't need to copycat my process, you're a free human being, consider me as your Build mentor :-o

1. "Build" process -
   1.1 Increment my build version (SolutionInfo.cs & AssemblyInfo.cs)
         In order to do that, I'm using a great code snippet I found during my last weekend searches to 
         create a new version number. Afterwards, I'm checking-out the SolutionInfo.cs file and imprint the 
         new AssemblyVersion using <asminfo> task.
         Eventually I'm checking-in the SolutionInfo.cs file.

         * I'm using some properties - ${property_name} - for easy maintenance, you can see it in the 
            file I've upload (way over down).

   <vsscheckout username="${vss.username}" password="${vss.password}" 
      localpath="${slndir}" recursive="false" writable="true" dbpath="${vss.dbpath}" 
      path="${vss.slnpath}/SolutionInfo.cs" failonerror="true" />

   <asminfo output="${slndir}\SolutionInfo.cs" language="CSharp">
      <imports>
         <import namespace="System" />
         <import namespace="System.Reflection"/>
         <import namespace="System.Runtime.CompilerServices"/>
      </imports>
      <attributes>
         <attribute type="AssemblyVersionAttribute" value="${build.version}" />
         <attribute type="AssemblyCompanyAttribute" value="${company}" />
         <attribute type="AssemblyProductAttribute" value="${product}" />
         <attribute type="AssemblyCopyrightAttribute" value="Copyright (c) 2005, ${company}." />
         <attribute type="AssemblyTrademarkAttribute" value="Trademark by ${company}" />
         <attribute type="AssemblyDelaySignAttribute" value="false" />
         <attribute type="AssemblyKeyFileAttribute" value="..//..//..//key.snk" />
         <attribute type="AssemblyKeyNameAttribute" value="" />
      </attributes>
   </asminfo>

   <vsscheckin username="${vss.username}" password="${vss.password}" 
      localpath="${slndir}\SolutionInfo.cs" recursive="false" writable="true" 
      dbpath="${vss.dbpath}" path="${vss.slnpath}/SolutionInfo.cs"
      comment="change build version: ${build.version}" />

         I use the same code (with minor changes) to update my AssemblyInfo.cs file as well.

   1.2 Put a label on the VSS with the current new version.
         This is even easier, I just use <vsslabel>(NAnt contrib) task:

      <vsslabel
           username="${vss.username}"
           password="${vss.password}"
           dbpath="${vss.dbpath}"
           path="${vss.slnpath}"
           comment="New build version: ${build.version}"
           label="${build.version}"
      />

   1.3 Get the files from the VSS to my local directory recursively using <vssget>(NAnt contrib) task.
      <vssget
           username="${vss.username}"
           password="${vss.password}"
           localpath="${vss.outdir}"
           recursive="true"
           replace="true"
           writable="false"
           dbpath="${vss.dbpath}"
           path="${vss.slnpath}"
      />

   1.4 If I'm required to (by property) - generate the projects pdb's.
        This is great for release mode, I can pull the pdb's for the version at the Production environment 
        and make some extreme production debugging using the pdb's as symbols - 
        I must give the credit to "The markowitz" for the idea !
      

        The code is quite simple - build the solution in Debug mode and copy the *.pdb files
        to my "version_directory"\pdb\WebProject.
        You can see the code in the attached file.

   1.5 Build the solution.
         I'm using <solution> task and <webmap> for easy build.
         Again, nothing fancy, look in the attached file.

   1.6 Copy the web project output to my MySolution\Builds\[version_number] directory for 
        an easy XCOPY deployment. I'm using <copywebproject> task in order to do 
        this magic, it's working like a charm.  
   <copywebproject project="${slndir}\WebApp\WebApp.csproj" 
      todir="${outdir}\WebApp" configuration="${config}" />

   
2. "Rebuild" process - 
      Call steps 1.3 to 1.6.

TIPS:
I recommend that you'll download VSTweak and let the VS.NET treat your .build file as .xml file.

TODO:
I'm going to add a NAnt task which will get all the *.js\*.htc files from the web project (.csproj) and format them
via Jazmin - this will cut down the size of the files(by removing comments and other not-required characters) for performance improvement (the smaller the file is, the faster the client will download it).

CREDIT:
If you're using my file as your "template", I would appreciate if you'll add a comment and let me know about it, including new features you've added or planning to add. I've dedicated my time to share with you, please do the same grace with me. Thanks !

My (template) build file:
default.zip (3 KB)

How to run the build file ?
You'll need to configure the default.build file I've attached (5 minutes max).
Go to your solution directory and copy the "default.build" file into it.
Now, activate "cmd" and navigate to that directory.
Type "nant build" and Voila !

   

Posted by Oren Ellenbogen 
30/07/2005 01:04, Israel time UTC-07:00,     Comments [2]  | 
# Thursday, July 28, 2005

Hey folks,

I'm sure that all of you encountered this message at least once in your life as a programmer.
Well, I've managed to understand and fix one aspect(\scenario) of the beast:

In my project, I have a directory named "References" which holds all my compiled (in Release mode of course) Dlls which are being used as "black box" component (i.e file reference). Because of all these files are in the VSS and I put them as "Solution Items"(easier deployment), they downloaded to my computer as "Read-only" files. So at the first time the solution builds, no problem, The web project can copy those Dlls (they are not exist in his bin directory), afterwards it's working fine as well (later builds) because there are no changes to this Dlls so the VS.NET simply don't copy them again (like "he" don't compile the ClassLibrary if no changes were made, he's a smart fellow you know).

BUT, in my scenario, I've updated one of those "black box" Dll and I tried to rebuild my solution. You can understand from the title that I got this annoying message that it can't copy the Dll. After I've checked a little, I found out the problematic file in my webproject\bin directory is checked as read-only, So I've unchecked it, rebuild the solution and it worked faultlessly.

If found 2 solutions for this problem:

  1. Call attrib -r [path-to-web-project]\bin\*.dll on pre-build (Build Event) of any ClassLibrary project; I would've put it in my WebProject project but unfortunately it doesn't support Build Events (why MS, why ?)
  2. Go to your "References" directory and manualy set all the files to *NOT* Read-only.
.NET | VSS
   

Posted by Oren Ellenbogen 
28/07/2005 11:32, Israel time UTC-07:00,     Comments [5]  | 
# Wednesday, July 27, 2005

For some reason, every time I closed my (specific) solution from Visual Studio .NET (2003) the IDE throw an "The operation could not be completed" error. After I've tried to open another(different) solution in the same IDE instance, the solution was not bounded to the VSS !
I swear, this is a regular solution structure... nothing fancy;
After digging a little, and talking about it with Amir (aka "The Markowitz"), we've come to the conclusion that the solution (*.sln) file have problems with the VSS. It became obvious when I tried to add a file to the Solution Items and I simply couldn't check-in the new file.

I've start googling about "troubleshoot VS.NET log" but no luck, I can't seem to find a log file which will give me some more data about the "The operation could not be completed" error. I hate the "restart-your-computer" solutions style, but after I've spent 2 hours exploring the *.sln files, *.csproj files and tried to reproduce the problem on a different solution(tester), I was getting tired and frustrated.

As last resort, I've unbounded the all solution, deleted (permanently) the $/MyProject directory from the VSS and reattached the all solution to the VSS again using the recommended guideline.

Now everything is good, weird ah ?

.NET | VSS
   

Posted by Oren Ellenbogen 
27/07/2005 12:03, Israel time UTC-07:00,     Comments [5]  | 
# Monday, July 25, 2005

Damn, such a long title... I must take a minute to relax; Done -

I had to change the directory name of my Web project in order to ease my build process.
Well, I must admit, this isn't an easy task when you don't remember the steps or you're too
tired to messing around with it (rule of thumb: gather the required powers, it won't get easier to adjust it later you know).

So, from my experience here are the steps for changing the VSS bounded ASP.NET project
directory name without killing your VSS\Solution:

  1. Close the solution if it's open (i.e - close the Visual Studio .NET).
  2. Create the new directory name you want to address the ASP.NET project into.
  3. Go to the IIS (Ctrl + Q -> iis, oh wait, assuming you've followed my advice and installed SlickRun) and change the virtual directory path to point to the new directory.
  4. Open the *.sln file with notepad (right-click->open with...) and find "SccLocalPath[number]" which points to your current(unwanted) directory name; overwrite the directory name with the new directory name.
  5. Delete the *.suo file - NOTICE: this is a hidden file so you must check the option to view all the hidden files (OS configuration). This file keeps the user configuration about the solution (like what is my StartUp project\file etc.)
  6. Open the *.sln via VS.NET and you'll get a window which will ask you to choose the web project path (http://localhost/VirtualDirectoryName_1) - remove the "_1" suffix and click OK.
  7. Delete the old web project directory. TIP: if you're trying to delete the old web project directory and you'll get an error that there are files in use - try to delete VSWebCach directory (in your c:\Documents and Settings\[username]) and then try to delete the directory again.
  8. Drink something and relax, you deserve it !
.NET | VSS
   

Posted by Oren Ellenbogen 
25/07/2005 07:41, Israel time UTC-07:00,     Comments [1]  | 
# Sunday, July 24, 2005

I'm struggling with myself about what's the best way now to create an automated build mechanism for my dotNET project. I read a lot during the last weekend about using Nant and Nant Contrib and I've managed to pull something off quite easily. * I'll upload the build file and my remarks about the process as soon as I'll finish (Can't wait ah ? ;-)).

I saw that Microsoft shipped their automated tool - MSBuild - with VS.NET 2005 (beta 2); But in order to make use of MSBuild in my v1.1 .NET framework, I'll need to do some DIRTY hacks which I don't seem to like in this case. You ask yourself why ?

1. This is a beta version, meaning the bugs will be all over me !

2. I personally think that using the beta version of any program in my Production environment is a big risk, too big in my opinion.

3. Let's say that I found a bug and I need to get it fixed; MS will cry that this version isn't supported in v1.1 framework (dah! that's why I did my dirty hack) and in any case it's only a beta and I need to wait for the final release - and they'll be right ! (damn, I hate when it happens).

4. NAnt is an old(sorry... but I mean it as a compliment) open source freeware - there are less bugs and I can always dig in and make the required changes !

Therefore, I'm thinking of staying with NAnt just until the final release of MSBuild will be available.

What do you think ?

   

Posted by Oren Ellenbogen 
24/07/2005 08:01, Israel time UTC-07:00,     Comments [0]  | 
# Friday, July 22, 2005

I'm always trying to make my project deployment as easy as possible.
 
One of the "problems" I've encountered is keeping my solution structure, that is:
- MySolutionDirectory
      - MyWebProject
      - MyBusinessLayerClassLibrary
      - MyDataAccessLayerClassLibrary
      - MyEntitiesClassLibrary
      - etc.
 
This is hard to do, especially when the "Add Web Project" creates a virtual directory in
my wwwroot directory by default which breaks my desired structure.
 
When I want to initialize the Solution or to pull the entire solution from the
VSS (e.g - on a new programmer station) I need to take these steps beforehand -
  1. Create the directory [solution-path]\[web-project\webservice name]
  2. Go to my IIS and add the required virtual directory which will redirect to step 1 path.
Otherwise, the VS.NET will create the web folders in my wwwroot automatically, which will again break my preferred structure.
In addition, in some of my solutions, I have more than 1 web project\webservice and repeating these steps can get very annoying.
 
So, after reading about IIS API, I've created an IIS helper utility for creating virtual directories by
demand in one-click EXE.
 
The configuration file is quite simple:

<VDSettings>
    <Directories>
        <Directory>
            <DirectoryPath>C:\Projects\MySolution\MyWebProject</DirectoryPath>
            <VirtualDirectoryName>MyWebProject</VirtualDirectoryName>

        </Directory>
        <Directory>
            <DirectoryPath>C:\Projects\MySolution\MyWebShareProject</DirectoryPath>
            <VirtualDirectoryName>MyWebShareProject</VirtualDirectoryName>
            <CreateUnder>MyWebShareProject</CreateUnder>
        </Directory>
    </Directories>
</VDSettings>

This sample demonstrates how to add "MyWebProject" Virtual Directory and create another
Virtual Directory, under "MyWebProject", named "MyWebShareProject".
 
* 2 Notes:
  1. You can create the virtual directory under a WebSite by using "WebSiteName" element under the "Directory" element.
  2. If the "DirectoryPath" doesn't exist - the utility will create it before setting the Virtual Directory path.
 
Now, when a co-worker in my company is trying to deploy my solution on his station, all he needs to
do is to run VDCreator.exe and he can continue the deployment via VS.NET -> "Open From Source Control..." option.
 
That's what I call "child's play" deployment.
 
The files:
VDCreator bin1.zip (4.62 KB)  (EXE & config file only)
VDCreator Source.zip (9.64 KB) (Source files included)
   

Posted by Oren Ellenbogen 
22/07/2005 12:38, Israel time UTC-07:00,     Comments [1]  | 
# Sunday, July 17, 2005

Add a new Solution and Projects to the VSS:
 
DONT -
Count on the VS.NET => "Add Solution to Source Control..." to add your solution
and projects to the VSS.
It will create such a mess in the VSS, a mess you'll find difficult to clean up later on, that you'll be
sorry for the moment you've chosen this option.
In addition, it will not give the desired (and recommended) structure:
 
MySolution
   - MyWebProject
   - MyClassLibrary1
   - MyClassLibrary2
   - ...
 
 
DO -
Follow the steps in this great post. I truly believe this link is a MUST
for every developer who's working with VS.NET and VSS on a daily basis.
 
I hope this will help you all...
 
 
 
 
.NET | VSS
   

Posted by Oren Ellenbogen 
17/07/2005 09:42, Israel time UTC-07:00,     Comments [2]  |