Tuesday, May 31, 2011

Using Command Pattern for multilevel Undo/ Redo functionality

The GangOfFour Command Pattern tells about the recurring design theme of separating execution of a command from its invoker allowing parameterize clients with different requests, queue or log requests, and support undoable operations
We can use the command pattern to implement multi-level undo/ redo functionality by tracking the commands executed in the context. For this we need a Command Manager to keep track of the commands on a stack that can be later used for Undo/ Redo execution of the commands.

The classes used in this sample looks like

Command.cs
public abstract class Command
{
    public abstract bool Execute();
}

UndoCommand.cs

public abstract class UndoCommand : Command
{
    public abstract bool Undo();
}

CommandManager.cs
public class CommandManager : Stack<Command>
{
    public UndoCommand PopCommand()
    {
        if (Count == 0) return default(UndoCommand);
        var command = Pop();
        while (!(command is UndoCommand))
        {
            if (Count == 0) return default(UndoCommand);
            command = Pop();
        }

        return command as UndoCommand;
    }

    public void AddCommand(Command command)
    {
        Push(command);
    }

    public Command GetLastCommand()
    {
        return Count == 0 ? default(Command) : Peek();
    }
}

A real world command implementation
public class CopyCommand : UndoCommand
{
    public CopyCommand(Document document)
    {
        if (document == null) throw new ArgumentNullException("document");
        _document = document;
    }

    public override bool Undo()
    {
        if(string.IsNullOrWhiteSpace(_previousSelection)) return false;
        _document.CopiedText = _previousSelection;

        return true;
    }

    public override bool Execute()
    {
        if(string.IsNullOrWhiteSpace(_document.SelectedText)) return false;
        _previousSelection = _document.CopiedText;
        _document.CopiedText = _document.SelectedText;
           
        return true;
    }

    private readonly Document _document;
    private string _previousSelection;
}

Testing the pattern
public class Document
{
    public Document()
    {
        InitializeCommands();
    }

    private void InitializeCommands()
    {
        _commandManager = new CommandManager();
        _copyCommand = new CopyCommand(this);
    }

    public void Copy()
    {
        var result = _copyCommand.Execute();
        if (result) _commandManager.AddCommand(_copyCommand);
    }

    public void Undo()
    {
        var undoCommand = _commandManager.PopCommand();
        if(undoCommand != default(UndoCommand)) undoCommand.Undo();
    }

    public void Redo()
    {
        var command = _commandManager.GetLastCommand();
        if (command != default(Command)) command.Execute();
    }

    public string CopiedText { get; set; }
    public string SelectedText { get; set; }

    private CopyCommand _copyCommand;
    private CommandManager _commandManager;
}

[TestMethod]
public void ExecuteMethodOnTheCommandShouldExecuteTheLogicForTheCommandObjectTest()
{
    var document = new Document();
    const string selectionText = "sample selection text";
    document.SelectedText = selectionText;
    document.Copy();
    Assert.IsTrue(document.CopiedText == selectionText);
}


[TestMethod]
public void CommandsShouldHaveUndoFunctionalityToRevertBackTheObjectToPreviousState()
{
    var document = new Document {CopiedText = "Previous selection"};
    const string selectionText = "sample selection text";
    document.SelectedText = selectionText;
    document.Copy();
    document.Undo();
    Assert.IsTrue(document.CopiedText == "Previous selection");
}

[TestMethod]
public void RedoShouldExecuteTheLastExecutedCommand()
{
    var document = new Document { CopiedText = "Previous selection" };
    const string selectionText = "sample selection text";
    document.SelectedText = selectionText;
    document.Copy();
    document.Redo();
    Assert.IsTrue(document.CopiedText == selectionText);
}

Monday, May 30, 2011

State Pattern Usage and Sample in C#

The state pattern implementation enables objects to encapsulate state-based behavior in discrete classes. Responsibilities are identified and delegated to appropriate states so that the object alters its behavior when it’s internal state changes. A simple example to demonstrate would be the order processing scenario.
For e.g. A new order is created for a product and submitted for approval. The order can be approved or rejected based on the availability of the stock or other details. Once the order is approved, it is scheduled for shipment and the scheduled date is set for the order. On the date of shipment, the order is processed and shipped to the shipping address. On arrival of the shipment the order is received and closed for further processing.
During the entire process email notifications are sent to various departments or personnel. For e.g. when an order is created an email notification is send to the Purchase order dept. manager about the details of the order. When it is submitted for approval an email is send to the person who is responsible for approving the order, on rejection or approval of the order the person or dept. who created the order will be notified about that.
This would lead to lot of conditional logic in the code to process the emails and other details based on the current state of the order. Applying the state pattern makes it easier for factoring the conditional statements to polymorphic behavior by delegating the tasks to the abstract OrderState instance.

The class diagram for the solution looks like.

The source code for the sample:
OrderState.cs
public abstract class OrderState
{
    internal readonly Order CurrentOrder;

    protected OrderState(Order currentOrder)
    {
        CurrentOrder = currentOrder;
    }

    public virtual bool IsNew
    {
        get { return false; }
    }

    public virtual bool IsSubmitted
    {
        get { return false; }
    }

    public virtual bool IsApproved
    {
        get { return false; }
    }

    public virtual bool IsRejected
    {
        get { return false; }
    }

    public virtual bool IsScheduled
    {
        get { return false; }
    }

    public virtual bool IsShipped
    {
        get { return false; }
    }

    public virtual bool IsClosed
    {
        get { return false; }
    }

    public IEmailServer EmailServer {get { return CurrentOrder.EmailServer;}}

    public abstract void Process();
    public abstract void Cancel();
    public abstract bool SendEmailsOnStatusChange();
}

NewOrderState.cs
public class NewOrderState : OrderState
{
    public NewOrderState(Order order) : base(order)
    { }

    public override bool IsNew
    {
        get { return true; }
    }

    public override void Process()
    {
        var isSuccess = CurrentOrder.SendNotifications();
        if (isSuccess)
            CurrentOrder.ChangeState(new SubmittedOrderState(CurrentOrder));
    }

    public override void Cancel()
    {
        CurrentOrder.ChangeState(new ClosedOrderState(CurrentOrder));
    }

    public override bool SendEmailsOnStatusChange()
    {
        var emailAddresses = CurrentOrder.GetPurchaseOrderDeptContacts();
        return EmailServer.Send(emailAddresses);
    }
}

Order.cs
public class Order
{
    public Order()
    {
        _currentState = new NewOrderState(this);
    }

    public bool IsNew
    {
        get { return _currentState.IsNew; }
    }

    public bool IsSubmitted
    {
        get { return _currentState.IsSubmitted; }
    }

    public bool IsApproved
    {
        get { return _currentState.IsApproved; }
    }

    public bool IsRejected
    {
        get { return _currentState.IsRejected; }
    }

    public bool IsScheduled
    {
        get { return _currentState.IsScheduled; }
    }

    public bool IsShipped
    {
        get { return _currentState.IsShipped; }
    }

    public bool IsClosed
    {
        get { return _currentState.IsClosed; }
    }

    public IEmailServer EmailServer { get; set; }

    public bool SendNotifications()
    {
        return _currentState.SendEmailsOnStatusChange();
    }

    public void ChangeState(OrderState orderState)
    {
        _currentState = orderState;
    }

    public void Process()
    {
        _currentState.Process();
    }

    public OrderState GetState()
    {
        return _currentState;
    }

    private OrderState _currentState;

    public IEnumerable<string> GetPurchaseOrderDeptContacts()
    {
        return new List<string> {"purchaseOrderDept@abcfirm.org"};
    }

    public IEnumerable<string> GetApproverEmailAddress()
    {
        return new List<string> {"approverEmail@abcFirm.org" };
    }
}

Testing the order sample
[TestMethod]
public void WhenNewOrderIsCreatedStateShouldBeNewTest()
{
    var target = new Order();
    Assert.IsTrue(target.IsNew);
}

[TestMethod]
public void WhenNewOrderIsProcessedShouldSendEmailsAndChangeStatusToSubmitted()
{
    var target = new Order {EmailServer = GetMockedEmailServer()};
    target.Process();
    Assert.IsTrue(target.IsSubmitted);
}

private IEmailServer GetMockedEmailServer()
{
    var mockedServer = new Mock<IEmailServer>();
    mockedServer.Setup((x) => x.Send(It.IsAny<List<string>>())).Returns(true);
    return mockedServer.Object;
}

Friday, May 6, 2011

IoC - Unity as a DI and Service Locator container

Inversion of control (IoC) is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming. Rather than a caller deciding how to use an object, in this technique the object called decides when and how to answer the caller, so the caller is not in charge of controlling the main flow of the application. This approach makes your code flexible enough to be decoupled.

Some of the main advantages of using IoC in your code are
  • Your code gets decoupled so you can easily exchange implementations of an interface with alternative implementations
  • It is a strong motivator for coding against interfaces instead of implementations
  • It's very easy to write unit tests for your code because it depends on nothing else than the objects it accepts in its constructor/setters and you can easily initialize them with the right objects in isolation.

The pattern is implemented through injecting dependencies into a component when it is constructed. These dependences are usually provided as interfaces for further decoupling and to support testability.

IoC can be implemented using many techniques as given below
  • Setter Injection
  • Constructor Injection
  • Interface Injection
  • Factory Pattern
  • Service Locator Pattern etc.

This post we'll see how to use the Unity Application block as a DI container and Service Locator implementation for implementation of the IoC pattern.

Sample object model used in the example.


Unit as a DI container
The example code we use has ViewModel which has a dependency on a CustomerRepository. The CustomerRepository is declared in the container and it is responsible to create and instance and resolve the dependency when the ViewModel is created. To specify the dependency we have decorated the constructor of the ViewModel with an [InjectionConstructor] attribute to specify that Unity will be in charge of creating this object at runtime.
public class CustomerViewModel
{
    [InjectionConstructor]
    public CustomerViewModel(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public void LoadCustomers()
    {
        Customers = new ObservableCollection<Customer>(_customerRepository.GetAll());
    }

    public ObservableCollection<Customer> Customers { get; set; }
    private readonly ICustomerRepository _customerRepository;
}

[TestClass]
public class CustomerViewModelFixture
{
    [TestInitialize]
    public void Initialize()
    {
        _container = new UnityContainer()
            .RegisterType<ICustomerRepository, CustomerRepository>()
            .RegisterType<CustomerViewModel>();
    }


    [TestMethod]
    public void LoadDataShouldLoadTheCustomersFromContextUsingDiTest()
    {
        var viewModel = _container.Resolve<CustomerViewModel>();
        viewModel.LoadCustomers();
        Assert.IsTrue(viewModel.Customers.Count > 0);
    }

    private IUnityContainer _container;
}

Unity as Service Locator
To use the Service Locator with Unity you need an adapter, which you can find on the CodePlex website at http://commonservicelocator.codeplex.com . You can create an adapter as given below.
_container = new UnityContainer()
    .RegisterType<ICustomerRepository, CustomerRepository>()
    .RegisterType<CustomerViewModel>();

var provider = new UnityServiceLocator(_container);
ServiceLocator.SetLocatorProvider(() => provider);

_serviceLocatorProvider = ServiceLocator.Current;

And then use this Service locator to resolve the dependencies in your code like.
var customerRepository = _serviceLocatorProvider.GetInstance<ICustomerRepository>();
var viewModel = new CustomerViewModel(customerRepository);
viewModel.LoadCustomers();
Assert.IsTrue(viewModel.Customers.Count > 0);