woensdag 28 maart 2012

Sharding with SQL Azure Federations is expensive


Since Microsoft introduced it's now pricing model in February 2012 SQL Azure has become a lot cheaper. However, when you partition your databases, the advantages of the new pricing model are lost.


Let me give you an example:
1 database of 10 GB will cost $45.95 per month.
10 partitioned databases of 1 GB each will cost 10 x $9.99 = $99.90


In other words, it's more cost effective to have one big database then to divide the database into several smaller databases. Which is a pity, because with several smaller databases you'll get better performance and parallelism (each database has its own cpu cores, memory, etc.).


Let's look at a few more examples, and see that the price difference can get pretty big:


1 database of 50 GB will cost $125.87 per month
10 databases of 5 GB will cost $259.74 per month


1 database of 50 GB will cost $125.87 per month
50 databases of 1 GB will cost $499.50 per month


1 database of 150 GB will cost $225.77 per month
150 databases of 1 GB will cost $1498.50 per month


Bottom line is that the more efficient your software is (with regards to performance of queries), the less need there will be to split a database into partitions. Ergo, efficient software will keep costs down. One quick win is to not use Entity Framework in places where you want efficient queries, but write them by hand. If for example you want to update a record, Entity Framework always does a select query first and then the update query. This can be rewritten into one query if you do it manually.

maandag 26 maart 2012

Domain Driven Development - Business Logic in Domain Objects (Part 2)

In Part 1 we saw how we can move Business Logic into Domain Objects. It was an easy example with a parent and a list of child objects. Let's look at a bit more complicated example.

Let's take for example this Business Rule:
When a Proposition is closed, no more Tasks can be added to the Phases of the Proposition.

If we build a simple system these three objects can look like this in code:

public class Proposition
{
   public int Id { getset; }
   public bool IsClosed {  get  set ; }
   public List<Phase> Phases {  get  set ; }
}

public class Phase
{
   public int Id { getset; }
   public List<Task> Tasks {  get  set ; }
   public  Proposition Proposition {  get  set ; }

   public void AddTask(Task task)
   {
      if(Proposition.IsClosed)
      {
         throw new Exception("Proposition is closed.");
      }
      Tasks.Add(task);
   }
}

public class Task
{
    public  string Name {  get   set ; }
}

And we can interact with Phase and Task like this:

var phase = PhaseRepository.GetById(1);
phase.AddTask(new Task());


What is the problem with this code?
The problem with the code above is that a child object (Phase) is depending on a parent object (Proposition). Why is that a problem? Because if we add another property to Proposition that has to be added to the Business Rule, we now have to edit two objects:

public class Proposition
{
   ...
    public int Value { getset; } 
} 



public class Phase
{
   public void AddTask(Task task)
   {
      if(Proposition.IsClosed)
      {
         throw new Exception("Proposition is closed.");
      }


      if(Proposition.Value > 100)
      {
         throw new Exception("Propositionvalue is more than 100.");
      }


      Tasks.Add(task);
   }
}


What is the solution?
One solution is to move this Business Rule to the Proposition object, like this:


public class Proposition
{
   public int Id { getset; }
   public bool IsClosed {  get  set ; }
   public List<Phase> Phases {  get  set ; }


   public void AddTask(Task task,  int phaseId)
   {
      if(IsClosed)
      {
         throw new Exception("Proposition is closed.");
      }


      if(Value > 100)
      {
         throw new Exception("Propositionvalue is more than 100.");
      }

       Phases.Single(it => it.Id ==  phaseId ).AddTask(task);
   }
}



public class Phase
{
   public int Id { getset; }
   private List<Task> _tasks;
   public  ReadOnlyCollection<Task> ReadOnlytasks
   {
      get
      {
         return new ReadOnlyCollection<Task>(_tasks);
      }
   }

   internal void AddTask(Task task)
   {
      Tasks.Add(task);
   } 

}

Note that AddTask in the Phase class is made internal, so it's only accessible to Proposition, and not in for example an MVC controller, or a business logic layer.

zondag 25 maart 2012

Readonly collections with Entity Framework

If you want to use readonly collections inside Domain Objects (like I did here) and are using Entity Framework Code First you currently have a problem, because collections of type ReadOnlyCollection are not supported.

Luckily I've found a way to work around this.

Let's start with an object which has a  ReadOnlyCollection :

public class Phase
{
   public int Id { getset; }
   public bool IsClosed { getset; }

   private List<Task> _tasks;
   public  ReadOnlyCollection<Task> ReadOnlyTasks
   {
      get
      {
         return new ReadOnlyCollection<Task>(_tasks);
      }
   }
} 

The problem with the code above is that Entity Framework can't map to private fields and it can't fill a ReadOnlyCollection.
What we can do is create a custom List which behaves like a readonly collection. For starters this means that the Add method is disabled:

public class ReadOnlyList<T> : List<T>
{
   /// <summary>
   ///  Not supported, because it's not allowed to add
   ///  items to a readonly list
   /// </summary>
   public new void Add(T item)
   {
      throw new NotSupportedException();
   }
}

Now we can use this  ReadOnlyList in our Domain Object:

public class Phase
{
   public int Id { getset; }
   public bool IsClosed { getset; }

   public ReadOnlyList<Task> ReadOnlyTasks
   {
      get;
      private set;
   }
}  

One problem solved: Entity Framework is able to fill the ReadOnlyList we created.
But now the Add method isn't supported anymore, how can we fill this list ourself? We have to create another add method, but this time we make it internal:

public class ReadOnlyList<T> : List<T>
{
   /// <summary>
   ///  Not supported, because it's not allowed to add
   ///  items to a readonly list
   /// </summary>
   public new void Add(T item)
   {
      throw new NotSupportedException();
   }

   internal  void AddItem(T item)
   {
      base.Add(item);
   }
}

We can use the AddItem method like this:

public class Phase
{
   public int Id { getset; }
   public bool IsClosed { getset; }

   public ReadOnlyList<Task> ReadOnlyTasks
   {
      get;
      private set;
   }

   public void AddTask(Task task)
   {
      ReadOnlyTasks.AddItem(task);
   }
}  

So how do we use the Phase class after we wrote this code? For example an MVC controller can look like this:

public ActionResult Index() 
{
   var phase = PhaseRepository.GetById(1);
   phase.AddTask(new Task());
} 

What would happen if we call the Add method on the ReadOnlyTasks list, like this:

public ActionResult Index() 
{
   var phase = PhaseRepository.GetById(1);
   phase.ReadOnlyTasks.Add(new Task());
} 

The code above will throw an  NotSupportedException, just as we wrote. So it is indeed a readonly list. But it's not very nice that we can call the Add method, the code compiles without any problem, but at runtime it will fail. It would be much nicer if we can do something to the Add method so we can't call it. Unfortunately we can't make it private or internal, because the public Add method of the List we inherited will become available. But there's another solution: mark the method with the System.Obsolete parameter, like this:

public class ReadOnlyList<T> : List<T>
{
   /// <summary>
   ///  Not supported, because it's not allowed to add
   ///  items to a readonly list
   /// </summary>
   [Obsolete("Not supported, because it is not allowed to add items to a readonly list", true)]
   public new void Add(T item)
   {
      throw new NotSupportedException();
   }
   ...
}

Now, if we try to call the Add method from an MVC Controller, we see this:





This helps us a lot by not making the mistake of calling Add on the readonly list. And if still continue, and type something like this:

phase.Tasks.Add(new Task());

We will get an error at compile time, so our code will never run. We now can only add items to the readonly list by calling the AddTask method on the Phase class, exactly as we wanted.


Btw. this solution is not completely air tight, because we can still cast our Readonly list to a List and the Add method is back available again. But at least we have a pretty clean solution for Readonly lists with Entity Framework.

Domain Driven Development - Business Logic in Domain Objects


Introduction
One of the recurring questions in developing software in C# is where to put Business Logic. It's quite easy to scatter Business Rules throughout the system, in such a way that it will be very hard to maintain the code.


Let's take for example this Business Rule:
When a Phase is closed, no more Tasks can be added to it.


If we build a simple system these two objects can look like this in code:


public class Phase
{
   public int Id { get; set; }
   public bool IsClosed {  get  set ; }
   public List<Task> Tasks {  get  set ; }
}


public class Task
{
    public  string Name {  get   set ; }
}


And we can interact with Phase and Task like this:


var phase = _phaseRepository.GetById(1);


if(!phase.IsClosed)
{
   phase.Tasks.Add(new Task());
}



What is the problem with this code?
The problem with the code above is that if in one place we forget to check if the Phase is closed, we can add Tasks to a closed Phase. So, mistakes are quite easy to make in this case.
Another problem is that we have to copy the check for IsClosed every time we want to add Tasks to a Phase in another part of the system.
And a third problem is that whenever we add another condition to the Business Rule, we have to go through all code where we Add Tasks and add code for the new condition.


What is the solution?
It's better to move this Business Rule to the Phase object, like this:


public class Phase
{
   public int Id { getset; }
   public bool IsClosed { getset; }
   public List <Task> Tasks { getset; }


   public void AddTask(Task task)
   {
      if(IsClosed)
      {
         throw new Exception("Can't add tasks to closed Phase.");
      }
      Tasks.Add( task );
   }
}

Now we can simply use the code above like this:

var phase = PhaseRepository.GetById(1);
phase.AddTask(new Task());




This looks a lot better. And if we add another property to the Phase which has to be checked when we add a Task, we only have to change the Phase object, and not the code in the controller.


We're not there yet
Although we now have a nice AddTask method, we can still easily get around it, because the List<Task> Tasks on Phase is public and has an Add method. So we can do this:


var phase = PhaseRepository.GetById(1);
phase.AddTask(new Task());
phase.IsClosed = true;
phase.Tasks.Add(new Task()); 


We can solve this by making the Tasks list readonly:


public class Phase
{
   public int Id { getset; }
   public bool IsClosed { getset; }

   private List<Task> _tasks;
   public  ReadOnlyCollection<Task> ReadOnlytasks
   {
      get
      {
         return new ReadOnlyCollection<Subforum>(_tasks);
      }
   }
}


And you will see that the Add methods isn't supported anymore. So everytime we want to add a Task to a Phase we have to use the AddTask method.


var phase = PhaseRepository.GetById(1);
phase.AddTask(new Task());
phase.Tasks.Add(new Task()); 


Entity Framework
So what if we use Entity Framework, does this solution work? No it doesn't work completely, because Entity Framework doesn't support ReadOnlyCollection<T>. But I have a solution for that, as you can read in the blog post I wrote:


Readonly collections with Entity Framework

zaterdag 17 maart 2012

Created a website to try Azure out

I've created www.BbsFactory.com which basically is a website with which you can create a hosted forum. So in other words it's a Forum as a Service.


This site helps me to try out things on Windows Azure, which works a lot better then trying yet another Hello World sample.