Saturday, September 4, 2010

N-Tiers using POCOs and Entity Framework - Part Two: Model and Entities

Following Domain Driven Design (DDD) principles [Evans, DDD], the domain should be represented by objects with state and behavior, using a rich object-oriented model. Additionally, in n-tier applications it is ideal to reuse as many objects as you could in order to reduce code duplication.

However, the object’s behavior is usually very different in each tier; for example, in the business tier the behavior is often business-oriented and it shouldn’t be executed in the presentation tier.

To solve this problem, we can use POCOs with only state (properties), and add behavior to them using extension methods in the business tier.

Model-Entities

Note: Although extension methods provide a good extensibility mechanism, they have some limitations. For example, they don’t support late-bound polymorphism (virtual methods).

In the following code snippet we can see the Order and Product POCOs, related each other through the Product and the Product_ID properties.

namespace Common.Domain.Entities
{
public class Order
{
public int Id { get; set; }
public Product Product { get; set; }
public int Product_ID { get; set; }
public int Quantity { get; set; }
...
}

public class Product
{
public int Id { get; set; }
public string Description { get; set; }
public int Stock { get; set; }
...
}
}

Note: EF supports two types of associations: Independent Associations (Product property) and Foreign Key Associations (Product_ID property). While the first ones are the most popular because are more object-oriented, the second ones are very useful in “disconnected” scenarios (e.g. when you need to update the relationship and you don’t have access to the EF context).


And as we mentioned before, the behavior of both objects is added using the extension methods defined in the following classes.

namespace Business.Domain.Entities
{
public static class OrderExtensions
{
public static void Confirm(this Order order) { ... }
public static void Cancel(this Order order) { ... }
...
}

public static class ProductExtensions
{
public static void SubstractStock(this Product product) { ... }
public static void RestoreStock(this Product product) { ... }
...
}
}

This allows us to call the specific domain behavior using the entity instance.


order.Confirm();

It is also important to mention that there are some scenarios where the entity does not match with the data that should be shown in the presentation layer, e.g. let’s say it is required to show the customer’s name and the description of the latest ten products that he or she ordered. In those cases it could be a better option to create a customized Data Transfer Object (DTO) in order to transfer over the wire only the data needed.


DTO


Note: If your architecture must support “cross-process change tracking”, I recommend you to use the “self-tracking entities” EF feature, an excellent feature designed for n-tier applications. Since it increases the amount of data that is sent over the wire, you should use this feature only if it is required.


References:

  • Evans, DDD: Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software, Boston, MA: Addison-Wesley 2004.

Posts in this series:

  1. Architecture
  2. Model and Entities

Wednesday, September 1, 2010

N-Tiers using POCOs and Entity Framework - Part One: Architecture

The ADO.NET Entity Framework comes with features like “persistence ignorance” and “POCO support” which allow the use of simple objects as persistent entities and the development of n-tier applications in an easier way.

The purpose of these post series is to show an example of an n-tier application that takes advantage of these features.

In n-tier architectures, each tier can be executed in a different process and potentially in a different server. In fact, every application that uses a database server and an internet browser has at least three tiers, so it could be considered an n-tier application. Nevertheless, in the .NET world it is very common to catalog as n-tier applications those in which the .NET code is separated by at least two processes, generally using technologies such as SOAP Web Services, .NET Remoting or Windows Communication Foundation (WCF).

The example application has the following architecture:

Architecture

The application’s architecture is split into two tiers:

  • The presentation tier, which has the responsibility to execute the user interface logic using the “Model-View-Controller” (MVC) pattern [Fowler, PEAA].
  • The business tier, which contains all the business and data access logic. This tier uses the “Unit of Work” and “Repository” patterns [Fowler, PEAA] combined with an Object Relational Mapper (Entity Framework).

In this architecture, the Model and the Entities are represented by the Plain Old CLR Objects (POCOs) that are serialized and transported over the wire between both tiers.

Tiers

Note: Plain Old CLR Objects (POCOs) are ordinary .NET classes without any infrastructure-related stuff. POCOs don’t have to inherit from a certain base class or to implement a specific interface. They are clean objects with persistence ignorance [Nilsson, ADDDP].

 

References:

  • Fowler, PEAA: Fowler, Martin. Patterns of Enterprise Application Architecture, Boston, MA: Addison-Wesley 2003.
  • Nilsson, ADDDP: Nilsson, Jimmy. Applying Domain-Driven Design and Patterns with examples in C# and .NET, Boston, MA: Addison-Wesley 2006.

Posts in this series:

  1. Architecture
  2. Model and Entities

Wednesday, February 3, 2010

WPF Commands in IronPython

Dependency Properties and Commands are very useful WPF features.

In my last post I wrote about how to use Dependency Properties in IronPython. In this post we will see how to implement and use the WPF RelayCommand (for more details see WPF Apps With The Model-View-ViewModel Design Pattern).

 

import clr

clr.AddReference("WindowsBase")
clr.AddReference("PresentationCore")
clr.AddReference("PresentationFramework")

from System import (
    EventArgs
)

from System.Windows import (
    DependencyObject
)

from System.Windows.Input import (
    ICommand
)

class RelayCommand(ICommand):

    def __init__(self, executeFunction, canExecuteFunction):
        self._executeFunction = executeFunction
        self._canExecuteFunction = canExecuteFunction
        self._handlers = []

    def CanExecute(self, parameter):
        return self._canExecuteFunction(parameter)

    def add_CanExecuteChanged(self, handler):
        self._handlers.append(handler)

    def remove_CanExecuteChanged(self, handler):
        self._handlers.remove(handler)

    def canExecuteChanged(self):
        for handler in self._handlers:
            handler(self, EventArgs.Empty)

    def Execute(self, parameter):
        self._executeFunction(parameter)
        self.canExecuteChanged()


class Planning(DependencyObject):

    _sessionProperty = None

    def __new__(cls):
       if not Planning._sessionProperty:
            Planning._sessionProperty = DependencyProperty.Register(
                "session", clr.GetClrType(Session), clr.GetClrType(Planning))   
        return DependencyObject.__new__(cls)

    def __init__(self):
        self.loginCommand = RelayCommand(lambda p : self.login(p), lambda p : not self.session)
    def login(self, user):
        self.session = Session(user)

    def getSession(self):
        return self.GetValue(Planning._sessionProperty)

    def setSession(self, value):
        self.SetValue(Planning._sessionProperty, value)

    session = property(getSession, setSession)

Saturday, January 30, 2010

WPF Dependency Properties in IronPython

One of the best features added to WPF are Dependency Properties. Dependency properties use a combination of a property and a static field (a class field in python).

As follows you will find an example:

import clr

clr.AddReference("WindowsBase")
clr.AddReference("PresentationCore")
clr.AddReference("PresentationFramework")

from System.Windows import (
DependencyObject, DependencyProperty
)


class Planning(DependencyObject):

_sessionProperty = None

def __new__(cls):
if not Planning._sessionProperty:
Planning._sessionProperty = DependencyProperty.Register(
"session", clr.GetClrType(Session), clr.GetClrType(Planning))
return DependencyObject.__new__(cls)

def getSession(self):
return self.GetValue(Planning._sessionProperty)

def setSession(self, value):
self.SetValue(Planning._sessionProperty, value)

session = property(getSession, setSession)

Monday, December 28, 2009

Using an IronPython object from C#

The new keyword “dynamic” added to C# (.Net 4.0) allows you to interoperate with any dynamic language such as IronPython or IronRuby.

This new feature bypasses any static type checking at compile time, assuming that any operation is allowed. But, if it is not allowed, an error will be showed at run time.

For example, the following Customer “IronPython Class” is invoked from the C# code as a dynamic object:


IronPython code (Sample.py)

# Function (method) that creates a new Customer
def CreateCustomer(firstName, lastName):
    return Customer(firstName, lastName)

# Customer object
class Customer(object): 

    # Initialization (constructor)
    def __init__(self, firstName, lastName):
        self._firstName = firstName
        self._lastName = lastName

    # Function (method) that print the customer
    def printNames(self):
        print self._firstName + ' ' + self._lastName


C# code (Program.cs)

using Microsoft.Scripting.Hosting;
using IronPython.Hosting;

class Program
{
    static void Main(string[] args)
    {

        ScriptRuntime py = Python.CreateRuntime();
        dynamic sample = py.UseFile("Sample.py");
        dynamic customer = sample.CreateCustomer("Paul", "Smith");
        customer.printNames();
    }
}


You can download the source code here.

Tuesday, December 22, 2009

Using PLINQ to improve performance

The version 4.0 of .Net has a new feature called “Parallel LINQ” or PLINQ. If you use LINQ to filter or process a large amount of objects in memory and/or it is required a high-cost evaluation, PLINQ is for you.

PLINQ segments the source in parts and it uses different threads in order to process each segment.

var validCustomers = allCustomers.AsParallel()
  .Where(c => c.IsValid())
  .ToArray();

PLINQ

Here you can download the sample code.

For more details I recommend you to watch the Igor Ostrovsky presentation in the PDC 2009 webpage.

Tuesday, December 1, 2009

Entity Framework 4.0 - Foreign Key Relationships

The current version of EF (v3.5) maps table relationships as properties, hiding database foreign-key columns. However, there are some scenarios where you don’t need the entire referenced object to do some operation, you only need its “Id” (foreign key).

For example, in a web application it is very common to use combo-boxes in order to assign relationships. In these scenarios, after a post-back it is necessary to re-create the model and its relationships (using combo-boxes “selected values”). Since you don’t have the referenced objects, you must get them from the database or use “Stub Entities” to simulate them.

To solve this problem, the version 4.0 will also allow you to map foreign-key columns as properties, making it easier.

More info: http://blogs.msdn.com/adonet/archive/2009/11/06/foreign-key-relationships-in-the-entity-framework.aspx.