Software Artisan's Blog

~ onLife >> onMusic >> onDesign >> onPatterns >> onRefactoring >> onAgile

Category Archives: C#

Exploring Concurrency CodeJugalbandi

06 Wednesday Feb 2019

Posted by Dhaval Dalal in APL, C#, Clojure, Code Jugalbandi, JavaScript, Scala

≈ Leave a comment


This time at Functional Conf 2018, Morten Kromberg, CXO of Dyalog Ltd., Ravindra Jaju and myself presented CodeJugalbandi again. The theme was about exploring concurrency. Conversations between the three artists can be viewed by clicking the links below, or you can simple watch the embedded Youtube video herein.

Melody Name Languages Used Examples
Concurrency and Parallelism Java and APL
  • Concurrency – Echo TCP Server
  • Parallelism – Splitting I/O Task – Portfolio Networth
FP to the Rescue (Etymology of structure of code) Scala, C#, Clojure, APL and JavaScript Gathering Weather and Nearby Places Information
Everything is an Event (Pushing Multiple Values) Reactive Extensions (Java) and Clojure CSP (Core-Async) Portfolio networth using Streaming Stock prices

At the conference, we could demo only first two melodies (see below for the video), The Github Repo has all the melodies mentioned herein.

Slides are simply an index to the melodies.

Note: Further work is in progress on creating other melodies under the theme Exploring Concurrency Codejugalbandi – Mutability, STM and the Actor Model.

Advertisements

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Introducing the WindowBuilder abstraction for WPF applications

12 Saturday May 2012

Posted by Dhaval Dalal in C#

≈ Leave a comment


In this second installment of the useful abstractions based on the earlier post, I’ll discuss about the WindowBuilder. There were quite a few scenarios where we wanted to pop-up a new window from the application, say for example, pop-up a Trade Ticket (in Read-Only as well as in Editable mode), the second is to pop-up an Exception Window when something goes wrong while processing, the third to display the main application window itself and so on… As this is a small application, we did not use Prism (for large applications, Prism is the way to go) for layouting, showing and hiding views etc…

This is how I expect the WindowBuilder to be invoked from Displayer

public class Displayer : IDisplayer
{
  private readonly IBinder binder;

  public Displayer(IBinder binder)
  {
    this.binder = binder;
  }

  public void OpenTradeTicket(Instrument instrument, Side side, int quantity, bool asReadOnly)
  {
    new WindowBuilder<TradeTicket, TradeTicketViewModel>(binder)
      .Bind(vm => vm.InstrumentCode, instrument.Code)
      .Bind(vm => vm.Side, side)
      .Bind(vm => vm.Quantity, quantity)
      .Bind(vm => vm.Price, instrument.Price)
      .Bind(vm => vm.AsReadOnly, asReadOnly)
      .Show();
  }
}

Here is another usage example:

try
{
     ...
}
catch(Exception exception)
{
  new WindowBuilder<ExceptionViewer, ExceptionViewerViewModel>(appCtx.Get<IBinder>())
    .Bind(vm => vm.Message, exception.Message)
    .Bind(vm => vm.Trace, exception.StackTrace)
    .Bind(vm => vm.TraceVisibility, true)
    .Show();
}

To achieve this, we evolved to this abstraction called the ViewBuilder, that builds the view and shows it on the screen.

public interface IViewBuilder<TView, TViewModel> where TView : Control
{
  IViewBuilder<TView, TViewModel> Bind<TProperty>(Expression<Func<TViewModel, TProperty>> propertyOrField, TProperty data);
  void Show();
}

Here is the concrete ViewBuilder that builds and displays window on the screen. It allows the user to bind the details on the Window before showing it on the screen. To achieve this, the WindowBuilder takes in a View and a ViewModel that that backs the view, populates the ViewModel proerties using the Binder from the earlier post and then finally tells the view to show itself.

public class WindowBuilder<TView, TViewModel> : IViewBuilder<TView, TViewModel> where TView : Window
{
  private readonly IBinder binder;
  private readonly TView view;
  private readonly TViewModel viewModel;

  public WindowBuilder(IBinder binder)
  {
    this.binder = binder;
    viewModel = binder.Bind<TView, TViewModel>(ref view);
  }

  public IViewBuilder<TView, TViewModel> Bind<TProperty>(Expression<Func<TViewModel, TProperty>> propertyOrField, TProperty data)
  {
    binder.Bind(viewModel, propertyOrField, data);
    return this;
  }

  public void Show()
  {
    view.Show();
  }
}

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Evolving to a ViewViewModelBinder for WPF applications

23 Monday Apr 2012

Posted by Dhaval Dalal in C#

≈ Leave a comment


In this post, i’ll describe how we evolved to Binder abstraction, step-by-step and on the way talk about other useful abstractions that help alleviate the problem of coupling.

Trading System Scenario: On the Pricing Grid, each instrument receives prices updates, user can click on either Buy or Sell column for an instrument in the grid and it pops up a TradeTicket (a Window). This Trade ticket has few fields like the Instrument Code, Side, Price (that keeps updating as the instrument ticks), quantity (a user entered field) and finally a button to submit the trade.

Lets say, the TradeTicket view is defined by the XAML below and it is backed by TradeTicketViewModel.

<Window x:Class="TradingApplication.Views.TradeTicket"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Trade Ticket"
    Name="tradeTicketWindow"
    Height="285"
    Width="300">

    <Window.Resources>
        <DataTemplate x:Key="ttvm" DataType="{x:Type ViewModels:TradeTicketViewModel}">
        </DataTemplate>
    </Window.Resources>
    <Grid DataContext="{StaticResource ttvm}">
</Window>

Here is the TradeTicketViewModel class.

public class TradeTicketViewModel : Notifier
{
  private readonly ITradingService tradingService;
  private readonly InstrumentUpdateEvent instrumentUpdateEvent;
  private Instrument instrument = Instrument.Empty;
  private double price;
  private Side side;

  public TradeTicketViewModel(ITradingService tradingService, IEventAggregator eventHub)
  {
    this.tradingService = tradingService;
    instrumentUpdateEvent = eventHub.GetEvent&lt;InstrumentUpdateEvent&gt;();
    instrumentUpdateEvent.Subscribe(OnPriceUpdateReceived);
  }

  public bool AsReadOnly { get; set; }
  public int Quantity { get; set; }
  public string InstrumentCode { get; set; }
  public Side Side { get; set; }

  public double Price
  {
    get { return price; }
    set
    {
      price = value;
      RaisePropertyChanged("Price");
    }
  }

  public ICommand SubmitTrade
  {
    get
    {
      return new RelayCommand(Execute, CanExecute);
    }
  }

  public ICommand QuantityEntered
  {
    get
    {
      return new ValidationCommand(AssignValidQuantity);
    }
  }

  private void AssignValidQuantity(object incomingQuantity)
  {
    int quantity;
    var isValidQuantityType = int.TryParse(incomingQuantity.ToString(), out quantity);
    var isValid = isValidQuantityType && IsValidQuantity(quantity);

    if (isValid)
    {
      Quantity = quantity;
      return;
    }
  }

  private bool IsValidQuantity(int quantity)
  {
    return quantity > 0;
  }

  private bool CanExecute(object obj)
  {
    return IsValidQuantity(Quantity) && !AsReadOnly;
  }

  public void Execute(object obj)
  {
    var trade = new Trade(Side)
    {
      Price = Price,
      Quantity = Quantity,
      InstrumentCode = InstrumentCode
    };
    tradingService.Submit(trade);
  }

  private void OnPriceUpdateReceived(Instrument instrument)
  {
    if(AsReadOnly)
    {
      return;
    }

    if (insrument.Code.Equals(InstrumentCode))
    {
      this.instrument = instrument;
      Price = GetPrice(instrument);
    }
  }

  private double GetPrice(Instrument instrument)
  {
    return (side == Side.Buy) ? instrument.Bid : instrument.Ask;
  }
}

Here is the Notifier implementation

public abstract class Notifier : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  protected void RaisePropertyChanged(string propertyName)
  {
    if (PropertyChanged != null)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
 }
}

Please refer to this article on the MSDN site for RelayCommand. Here is the ValidationCommand Implementation:

public class ValidationCommand : ICommand
{
  private readonly Action<object> callback;

  public ValidationCommand(Action<object> callback)
  {
    this.callback = callback;
  }

  public void Execute(object parameter)
  {
    callback.Invoke(parameter);
  }

  public bool CanExecute(object parameter)
  {
    return true;
  }

  public event EventHandler CanExecuteChanged;
}

The XAML above will create the ViewModel instance at View Level. The Trading Service and Event Aggregator, lets say are Singleton-ish within the application and so the DataTemplate defined at the TradeTicket view level will not help much. Also, XAML requires a parameterless constructor on TradeTicketViewModel, but what we have is a parameterized constructor that takes in two collaborators

  • Trading Service for submiting trades
  • and Event Aggregator to receive price updates for that instrument

One option is to use the setter in the XAML. But good OO design principles tell us to inject the dependent collaborator without whom the object cannot function during object creation and not inject via setter. So, lets rule out the setter option.

So, the next option is to move the DataTemplate, at a higher level, say application level where we can access and set these collaborators. There are two ways in which this can be done. One is to define it inline within in the Application XAML and have that ViewModel available to the entire application.

<Application x:Class="TradingApplication"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <!-- This is will create the ViewModel instance at Application Level and not View Level -->
        <DataTemplate x:Key="ttvm" DataType="{x:Type ViewModels:TradeTicketViewModel}" />
    </Application.Resources>
</Application>

Another is to use the Resource Dictionary (this will be residing in a external file). This is also helpful when you want to share resources across applications (a rare re-use scenario for ViewModels atleast, for Styles, Themes its understandable). Resource Dictionary is a XAML based file and it will contain the above DataTemplate definition

<Application x:Class="TradingApplication"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary Source="filePath" />
    </Application.Resources>
</Application>

However, Resource Dictionary is primarily intended to instantiate viewy stuff like Themes, Shaders etc… and not instantiate Models for Views (avoid mixing concerns). So, inside XAML, you really don’t want to:

  • create view model instances
  • and bind view model instances to view

So, Application XAML and Resource Dictionary are ruled out as well. What is another place where you could instantiate ViewModels? Lets take a look at the possibility of using the XAML Code Behind, where we can create the ViewModel and bind the Data Context. In there, one could do the following:

public partial class TradeTicket : Window
{
  public TradeTicket()
  {
    InitializeComponent();
    ITradingService tradingService = //Get Reference from somewhere
    IEventAggregator eventHub = //Get Reference from somewhere
    //Bind the DataContext here.
    DataContext = new TradeTicketViewModel(tradingService, eventHub);
  }
}

But, from a pure MVVM perspective, you really don’t want to see any non-View related stuff happening in the Code Behind. The only view-related stuff is, InitializeComponent(), whereas rest is creation of the ViewModel, getting references to the collaborators, injecting them in the ViewModel and finally binding to the DataContext.

So, we need to move this out from here, but where? It would be nice, if I have some abstraction like ApplicationContext and tell it to create a fresh instance of the ViewModel whenever required. It is the responsibility of the ApplicationContext to create and wire up the collaborators and dole out a fresh ViewModel instance when asked for. Here is how the above code would then look like:

public partial class TradeTicket : Window
{
  public TradeTicket()
  {
    InitializeComponent();
    //Bind the DataContext here.
    DataContext = ApplicationContext.Instance.Get<TradeTicketViewModel>();
  }
}

Here is the Application Context code. In my case, the ApplicationContext is based on Unity IoC, alternatively, you could use Spring.NET as your IoC container.

public class ApplicationContext
{
  private readonly IUnityContainer unity;
  private static readonly ApplicationContext instance = new ApplicationContext();

  public static ApplicationContext Instance
  {
    get
    {
      return instance;
    }
  }

  private ApplicationContext()
  {
    unity = new UnityContainer();
  }

  public void RegisterType<TType, TImpl>(Scope scope) where TImpl : TType
  {
    unity.RegisterType<TType, TImpl>(GetLifetimeManager(scope));
  }

  public void RegisterType<T>(Scope scope)
  {
    unity.RegisterType<T>(GetLifetimeManager(scope));
  }

  public void RegisterInstance<T>(T anObject, Scope scope)
  {
    unity.RegisterInstance(typeof(T), anObject, GetLifetimeManager(scope));
  }

  public void RegisterInstance<TType, TImpl>(TImpl anObject, Scope scope) where TImpl : TType
  {
    unity.RegisterInstance(typeof(TType), anObject, GetLifetimeManager(scope));
  }

  public TType Get<TType>()
  {
    return unity.Resolve<TType>();
  }

  public Dispatcher GetApplicationDispatcher()
  {
    return Application.Current.Dispatcher;
  }

  private LifetimeManager GetLifetimeManager(Scope scope)
  {
    switch (scope)
    {
      case Scope.Singleton:
        return new ContainerControlledLifetimeManager();

      case Scope.Prototype:
        return new TransientLifetimeManager();

      case Scope.Request:
        return new PerThreadLifetimeManager();
    }
    throw new ArgumentException(string.Format("Undefined Lifetime Scope: {0}", scope));
  }
}

ApplicationContext can be be instantiated at the Application level, in the application code behind. Take a look at the creation of ApplicationContext and registration of types with it.

public partial class TradingApplication : Application
{
  private ApplicationContext appCtx;

  public TradingApplication()
  {
    //Create Application Context Instance
    appCtx = ApplicationContext.Instance;
  }

  protected override void OnStartup(StartupEventArgs e)
  {
    RegisterMainView();
    RegisterInfraStructureServices();
    RegisterViewModels();
    RegisterViews();
  }

  private void RegisterMainView()
  {
    appCtx.RegisterType<MainView>(Scope.Singleton);
  }

  private void RegisterViewModels()
  {
    appCtx.RegisterType<TradeTicketViewModel>(Scope.Prototype);
  }

  private void RegisterViews()
  {
    appCtx.RegisterType<TradeTicket>(Scope.Prototype);
  }

  private void RegisterInfraStructureServices()
  {
    appCtx.RegisterType<IEventAggregator, EventAggregator>(Scope.Singleton);
    appCtx.RegisterType<IBinder, ViewViewModelBinder>(Scope.Singleton);
    appCtx.RegisterType<ITrader, Server.Trading.Service.Trader>(Scope.Singleton);

    var tradingService = new TradingService(clientId, appCtx.Get<ITrader>());
    appCtx.RegisterInstance(tradingService, Scope.Singleton);
  }
}

So far so good, we have been able to move out the creation and wiring business to the ApplicationContext, we still have to get rid of the last line; binding to the DataContext.

Now, lets think how a user would perform a trade; pricing grid is the place where user will click on instrument row (either on the Bid or the Ask cell) and we should be able to pop-up a TradeTicket Window that is backed by the TradeTicketViewModel. The user then enters the quantity and hits Submit button to make a deal. For the user to do this effectively, we should show some of the instrument details on the ticket, that is, bind the row data, like the Instrument Code, Side and Price (current and continue to refresh updates) to the TradeTicket view’s DataContext to be displayed on the View.

Clearly there are many things involved here:

  • Passing Data from Grid row to View
  • Initialize required properties on ViewModel from row data.
  • Bind the view DataContext to the ViewModel
  • Finally, show the view.

In the current context of discussion, two items are of importance to us, i.e., Bind required properties on to ViewModel and finally bind the View’s DataContext to the ViewModel. This calls for a role of Binder that can own that responsibility. Here is the what the Binder can do:

public interface IBinder
{
  TViewModel Bind<TView, TViewModel>(ref TView view) where TView : FrameworkElement;
  TViewModel Bind<TView, TViewModel>(TView view, TViewModel viewModel) where TView : FrameworkElement;
  IBinder Bind<TTarget, TProperty>(TTarget target, Expression<Func<TTarget, TProperty>> propertyOrField, TProperty data);
}

Here is the concrete implementation of the Binder.

public class ViewViewModelBinder : IBinder
{
  private readonly ApplicationContext appContext = ApplicationContext.Instance;

  public TViewModel Bind<TView, TViewModel>(ref TView view) where TView : FrameworkElement
  {
    if (view == null)
    {
      view = appContext.Get<TView>();
    }
    var viewModel = appContext.Get<TViewModel>();
    return Bind(view, viewModel);
  }

  public TViewModel Bind<TView, TViewModel>(TView view, TViewModel viewModel) where TView : FrameworkElement
  {
    view.DataContext = viewModel;
    return viewModel;
  }

  public IBinder Bind<TTarget, TProperty>(TTarget target, Expression<Func<TTarget, TProperty>> propertyOrField, TProperty data)
  {
    SetPropertyOrFieldWithData(target, propertyOrField, data);
    return this;
  }

  private void SetPropertyOrFieldWithData<T, TProperty>(T t, Expression<Func<T, TProperty>> propertyOrField, TProperty data)
  {
    var propertyExpression = propertyOrField.Body as MemberExpression;

    if (propertyExpression == null)
    {
      throw new ArgumentException("Expecting Property or Field Expression of an object");
    }
    var targetExp = Expression.Parameter(typeof(T), "target");
    var propertyExp = Expression.PropertyOrField(targetExp, propertyExpression.Member.Name);
    var valueExp = Expression.Parameter(propertyExpression.Type, "value");
    var assignExp = Expression.Assign(propertyExp, valueExp);
    var expression = Expression.Lambda<Action<T, TProperty>>(assignExp, targetExp, valueExp);
    var assignPropertyValueTo = expression.Compile();
    assignPropertyValueTo(t, data);
  }
}

Now, the Binder can be used it like this:

var binder =
 new ViewViewModelBinder>TradeTicket, TradeTicketViewModel>()
    .Bind(vm => vm.InstrumentCode, row.InstrumentCode)
    .Bind(vm => vm.Side, row.Side)
    .Bind(vm => vm.AsReadOnly, false);

By evolving this ViewViewModelBinder, we do not need any DataContext binding in the View now. Thus the, TradeTicket code behind will now be just reduced to

public partial class TradeTicket : Window
{
  public TradeTicket()
  {
    InitializeComponent();
  }
}

Phew! That was quite a long post, but it did not make sense to split it in to many. There are other interesting abstractions that I will cover in subsequent posts helping us retain the pure MVVM approach and not pollute the ViewModel with view-related concerns.

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

C# for Java Developers

17 Saturday Mar 2012

Posted by Dhaval Dalal in C#, Java

≈ 2 Comments


Last week, at my current workplace, I did a demo session on C# for Java Developers. Here is the slide deck.

C# for-java-developers

View more presentations from Dhaval Dalal

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Equals, HashCode and ToString Builders in C#

16 Friday Mar 2012

Posted by Dhaval Dalal in C#

≈ 6 Comments


I know this is a long post, but I think it just makes sense to put all the three in here. I have used the Linq Expressions to achieve the builders that would generate HashCode, build the String representation for an object and finally compare the two objects for equality based on the fields or properties that a user defines should participate during the creation of the Hashcode, the string representation and to determine the equality of the objects.

So, lets say I have a Money class and I want to be able to implement the Equals, GetHashCode and the ToString implementations for it as shown below:

public class Money
{
  public string Currency { get; set; }
  public double Amount { get; set; }

  public override string ToString()
  {
    return new ToStringBuilder<Money>(this)
      .Append(m => m.Currency)
      .Append(m => m.Amount)
      .ToString();
  }

  public override bool Equals(object that)
  {
    return new EqualsBuilder<Money>(this, that)
      .With(m => m.Amount)
      .With(m => m.Currency)
      .Equals();
  }

   public override int GetHashCode()
   {
     return new HashCodeBuilder<Money>(this)
       .With(m => m.Amount)
       .With(m => m.Currency)
       .HashCode;
  }
}

In all the builders below, a common theme runs across – Accept the Linq Expression, Compile it so that it returns the delegate represented by the lambda and eventually invoke it by passing in the target object. The supplier of the delegate can return the appropriate value of the property or field on Type T, whose value would then be utilized for either equals comparison, or hashcode generation or to build the string representation of that object. Take a look at the EqualsBuilder below and its corresponding tests.

public class EqualsBuilder<T>
{
  private readonly T left;
  private readonly object right;
  private bool areEqual = true;

  public EqualsBuilder(T left, object right) {
    this.left = left;
    this.right = right;

    if (ReferenceEquals(left, right))
    {
      areEqual = true;
      return;
    }

    if (ReferenceEquals(left, null))
    {
      areEqual = false;
      return;
    }

    if (ReferenceEquals(right, null))
    {
      areEqual = false;
      return;
    }

    if (left.GetType() != right.GetType())
    {
      areEqual = false;
      return;
    }
  }

  public EqualsBuilder<T> With<TProperty>(Expression<Func<T, TProperty>> propertyOrField)
  {
    if (!areEqual)
    {
      return this;
    }

    if (left == null || right == null)
    {
      return this;
    }

    var expression = propertyOrField.Body as MemberExpression;
    if (expression == null)
    {
      throw new ArgumentException("Expecting Property or Field Expression of an object");
    }

    Func<T, TProperty> func = propertyOrField.Compile();
    TProperty leftValue = func(left);
    TProperty rightValue = func((T)right);

    if (leftValue == null && rightValue == null)
    {
      areEqual &= true;
      return this;
    }

    if (leftValue != null && rightValue == null)
    {
      areEqual &= false;
      return this;
    }

    if (leftValue == null && rightValue != null)
    {
      areEqual &= false;
      return this;
    }

    areEqual &= leftValue.Equals(rightValue);
    return this;
  }

  public bool Equals()
  {
    return areEqual;
  }
}

Here is the specification that I used to Test-Drive the above implementation

using Assert = NUnit.Framework.Assert;
using Is = NUnit.Framework.Is;
using Specs = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute;
using Specification = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
using Moq;

[Specs]
public class EqualsBuilderSpecs
{
  [Specification]
  public void ItEvaluatesEqualPropertyValueOfAnObjectToTrue()
  {
    //Given
    var left = new Money { Currency = "INR" };
    var right = new Money { Currency = "INR" };
    var builder = new EqualsBuilder<Money>(left, right);

    //When
    builder.With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.True);
  }

  [Specification]
  public void ItEvaluatesUnEqualPropertyValueOfAnObjectToFalse()
  {
    //Given
    var left = new Money { Currency = "USD" };
    var right = new Money { Currency = "INR" };
    var builder = new EqualsBuilder<Money>(left, right);

    //When
    builder.With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  [ExpectedException(typeof(ArgumentException), "Expecting Property or Field Expression of an object")]
  public void ItDoesNotEvaluateNonFieldsAndNonProperties()
  {
    //Given
    var left = new Money { Currency = "USD" };
    var right = new Money { Currency = "INR" };
    var builder = new EqualsBuilder<Money>(left, right);

    //When
    builder.With(m => m.GetType());
  }

  [Specification]
  public void ItEvaluatesEqualPropertiesOfAnObjectToTrue()
  {
    //Given
    var left = new Money { Currency = "INR", Amount = 4 };
    var right = new Money { Currency = "INR", Amount = 4 };
    var builder = new EqualsBuilder<Money>(left, right);

    //When
    builder
      .With(m => m.Currency)
      .With(m => m.Amount);

    //Then
    Assert.That(builder.Equals(), Is.True);
  }

  [Specification]
  public void ItEvaluatesUnEqualPropertyValuesOfAnObjectToFalse()
  {
    //Given
    var left = new Money { Currency = "USD", Amount = 23 };
    var right = new Money { Currency = "INR", Amount = 4 };
    var builder = new EqualsBuilder<Money>(left, right);

    //When
    builder
      .With(m => m.Currency)
      .With(m => m.Amount);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  public void ItShortCircuitsEqualsEvaluationWhenTheFirstPropertyEvaluatesToFalse()
  {
    //Given
    var left = new Mock<Money>();
    var right = new Mock<Money>();

    left.SetupGet(m => m.Currency).Returns("INR");
    left.SetupGet(m => m.Amount).Returns(4);

    right.SetupGet(m => m.Currency).Returns("USD");
    right.SetupGet(m => m.Amount).Returns(3);

    //When
    var builder = new EqualsBuilder<Money>(left.Object, right.Object)
      .With(m => m.Currency)
      .With(m => m.Amount);

    //Then
    Assert.That(builder.Equals(), Is.False);
    left.VerifyGet(m => m.Currency);
    right.VerifyGet(m => m.Currency);
    left.VerifyGet(m => m.Amount, Times.Never());
    right.VerifyGet(m => m.Amount, Times.Never());
  }

  [Specification]
  public void ItEvaluatesNullComparisonsToTrue()
  {
    //Given
    var left = new Money { Currency = null };
    var right = new Money { Currency = null };

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.True);
  }

  [Specification]
  public void ItEvaluatesNullAndValidValueToFalse()
  {
    //Given
    var left = new Money { Currency = null };
    var right = new Money { Currency = "INR" };

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  public void ItEvaluatesValidValueAndNullToFalse()
  {
    //Given
    var left = new Money { Currency = "INR" };
    var right = new Money { Currency = null };

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
 }

  [Specification]
  public void ItEquatesValidMoneyWithNullObjectAsFalse()
  {
    //Given
    var left = new Money { Currency = "INR" };
    object right = null;

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  public void ItEquatesNullMoneyWithValidMoneyAsFalse()
  {
    //Given
    Money left = null;
    var right = new Money { Currency = "INR" };

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  public void ItEquatesMoneyWithOtherTypeAsFalse()
  {
    //Given
    Money left = new Money { Currency = "INR" };
    var right = new { Length =20 };

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.False);
  }

  [Specification]
  public void ItEquatesNullMoniesAsTrue()
  {
    //Given
    Money left = null;
    Money right = null;

    //When
    var builder = new EqualsBuilder<Money>(left, right)
      .With(m => m.Currency);

    //Then
    Assert.That(builder.Equals(), Is.True);
  }
}

Here is the Hash code builder.

public class HashCodeBuilder<T>
{
  private readonly T target;
  private int hashCode = 17;

  public HashCodeBuilder(T target)
  {
    this.target = target;
  }

  public HashCodeBuilder<T> With<TProperty>(Expression<Func<T, TProperty>> propertyOrField)
  {
    var expression = propertyOrField.Body as MemberExpression;
    if (expression == null)
    {
      throw new ArgumentException("Expecting Property or Field Expression of an object");
    }

    var func = propertyOrField.Compile();
    var value = func(target);
    hashCode += 31 * hashCode + ((value == null) ? 0 : value.GetHashCode());
    return this;
  }

  public int HashCode
  {
    get
    {
      return hashCode;
    }
  }
}

Here is the ToStringBuilder

public class ToStringBuilder<T>
{
  private readonly T target;
  private readonly string typeName;
  private const string DELIMITER = "=";
  private IList<string> values = new List<string>();

  public ToStringBuilder(T target) {
    this.target = target;
    typeName = target.GetType().Name;
  }

  public ToStringBuilder<T> Append<TProperty>(Expression<Func<T, TProperty>> propertyOrField)
  {
    var expression = propertyOrField.Body as MemberExpression;
    if (expression == null) {
      throw new ArgumentException("Expecting Property or Field Expression");
    }
    var name = expression.Member.Name;
    var func = propertyOrField.Compile();
    var returnValue = func(target);
    string value = (returnValue == null) ? "null" : returnValue.ToString();
    values.Add(name + DELIMITER + value);
    return this;
  }

  public override string ToString()
  {
    return typeName + ":{" + string.Join(",", values) + "}";
  }
}

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Converting Xml to Object representation using C# dynamic and ExpandoObject

12 Monday Mar 2012

Posted by Dhaval Dalal in C#

≈ Leave a comment


Playing around with the new features of C# 4.0, I was able to put ExpandoObject and dynamic to some real use. Lets say we have this Xml configuration to parse and extract the node values and attributes value

<configuration>
     <pageappearance remoteonly="true">
         <color background="000000" foreground="FFFFFF"></color>
         <border>Solid</border>
    </pageappearance>
</configuration>

I would like to access the object that represents the Xml by traversing the nodes using the object graph traversal notation, some thing like the one show below

var configXml = "Solid";

XmlDocument document = new XmlDocument();
document.LoadXml(configXml);

//See XmlDocumentExtension
var config = document.ToObject();
Console.Out.WriteLine(config.PageAppearance.RemoteOnly); //true
Console.Out.WriteLine(config.PageAppearance.Color.Foreground); //FFFFFF
Console.Out.WriteLine(config.PageAppearance.Border);//Solid

So I ended up writing an XmlDocumentExtension class that does that

public static class XmlDocumentExtension
{
  public static dynamic ToObject(this XmlDocument document)
  {
    XmlElement root = document.DocumentElement;
    return ToObject(root, new ExpandoObject());
  }

  private static dynamic ToObject(XmlNode node, ExpandoObject config, int count = 1)
  {
    var parent = config as IDictionary&lt;string, object&gt;;
    foreach (XmlAttribute nodeAttribute in node.Attributes)
    {
      var nodeAttrName = nodeAttribute.Name.Capitalize();
      parent[nodeAttrName] = nodeAttribute.Value;
    }
    foreach (XmlNode nodeChild in node.ChildNodes)
    {
      if (IsTextOrCDataSection(nodeChild))
      {
        parent["Value"] = nodeChild.Value;
      }
      else
      {
        string nodeChildName = nodeChild.Name.Capitalize();
        if (parent.ContainsKey(nodeChildName))
        {
          parent[nodeChildName + "_" + count] = ToObject(nodeChild, new ExpandoObject(), count++);
        }
        else
        {
          parent[nodeChildName] = ToObject(nodeChild, new ExpandoObject());
        }
     }
    }
    return config;
  }

  private static bool IsTextOrCDataSection(XmlNode node)
  {
    return node.Name == "#text" || node.Name == "#cdata-section";
  }
}

The above can be easily used in a custom implementation of IConfigurationSectionHandler to parse the incoming section xml and convert it to a object graph for dot traversal, thus avoiding the need to write ConfigurationSection and ConfigurationElement implementations for section elements in App.config or Web.config

Any other scenario where you need to parse the incoming XML, say for example receiving an XML response from a Service or any messaging system, you can use the above XMLDocumentExtension and avoid creating abstractions that represent the XML document structure.

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Integrating PartCover for NAnt builds

28 Tuesday Apr 2009

Posted by Dhaval Dalal in C#

≈ 3 Comments


NCover has gone commercial and I needed a replacement…googling for Open Source Code Coverage Tool in C# yielded PartCover. I integrated PartCover to calculate code coverage in our NAnt build. In summary, in this post, I have shown:

  1. Using PartCover.
  2. Tweaking PartCover’s XSLTs to suit my needs.
  3. Generating Coverage Summary Index Page.
  4. Failing the build when coverage drops below a desired level.

1. Using PartCover:
Unlike NCover, PartCover does not have a NAnt task, its easy to write one, but not when one is racing against time…so I ended up using the standard “exec” task to implement code coverage calculation as a part of the build. Below are set of targets that I created to incorporate PartCover:

<!-- Reports Artifacts Publish Directory -->
<property name="reports.dir.root" value="reports" overwrite="false" />

<!-- Index.html for all types of reports -->
<property name="index.file.name" value="index.html" overwrite="false" />

<target name="set.coverage.properties">
  <!-- PartCover Related Properties -->
  <property name="partcover.base.dir" value="${root.dir}/${src.dir.root}/ReferenceLibraries/PartCover-2.2" dynamic="true" />
  <property name="partcover.exe" value="${partcover.base.dir}/PartCover.exe" dynamic="true"/>
  <property name="partcover.report.xsl" value="${root.dir}/build-common/coverage/common-partcover-report.xslt" />
  <property name="coverage.report.css.file.name" value="coverage-report.css" />
  <property name="coverage.report.css.file" value="${root.dir}/build-common/coverage/${coverage.report.css.file.name}" />

  <property name="coverage.result.file.prefix" value="CoverageResult-" overwrite="false" />
  <property name="coverage.result.file" value="${coverage.result.file.prefix}${include.coverage.assembly}" dynamic="true" overwrite="true"/>
  <property name="coverage.reports.dir.root" value="${reports.dir.root}/coverage" overwrite="false"/>
  <property name="coverage.baseline" value="75" overwrite="false"/>

  <!-- Assemblies for which a Test project wants to calculate coverage -->
  <property name="include.coverage.assembly" value="*" overwrite="true" dynamic="true" />
</target>

<target name="calculate.coverage" depends="init" description="Calculate Code Coverage using PartCover" verbose="true">
  <exec program="${partcover.exe}" workingdir="." failonerror="false">
    <arg value="--target '${root.dir}${src.dir.root}ReferenceLibrariesNUnit-2.4.8nunit-console.exe'" />
    <arg value="--target-work-dir '${root.dir}${src.dir.root}ReferenceLibrariesNUnit-2.4.8'"/>
    <arg value="--target-args '../${module.bin.dir}/${project.output}'" />
    <arg value="--include '[${include.coverage.assembly}]*'" />
    <arg value="--exclude '[nunit*]*'" />
    <arg value="--exclude '[log4net*]*'" />
    <arg value="--exclude '[Iesi*]*'" />
    <arg value="--exclude '[NHibernate*]*'" />
    <arg value="--exclude '[Castle*]*'" />
    <arg value="--exclude '[Rhino*]*'" />
    <arg value="--exclude '[${module.prefix}.*Test*]*'" />
    <arg value="--exclude '[${module.prefix}.*]*Test'" />
    <arg value="--output '${module.bin.dir}/${coverage.result.file}.xml'" />
  </exec>
</target>

2. Tweaking PartCover’s XSLTs:
PartCover, by default, generates coverage results in XML and we need to transform it to HTML using XSLT. Also, PartCover provides two levels of reports, one report is by assemblies and another by classes…however, it was more meaningful for us to see both these reports as one. So, I ended up creating another XSL:

  • New XSL is composed of the two individual XSLs provided by PartCover (of course, they too are tweaked!).
  • Parameterized the above XSL by passing in parameters from NAnt build.
  • Styles were refactored out to a separate CSS (coverage-report.css).

You can download all the stylesheets from here (please change the extension to .rar after download as Jroller does not allow rars pr zips to be uploaded) and place them inside build-common/coverage directory.

<target name="generate.coverage.report" depends="calculate.coverage" description="Prepare HTML Report by Assembly and Classes">
  <tstamp property="coverage.report.generation.datetime" pattern="dd-MMM-yyyy HH:mm:ss" />
  <style style="${partcover.report.xsl}" in="${module.bin.dir}/${coverage.result.file}.xml" out="${root.dir}${coverage.reports.dir.root}${coverage.result.file}.html">
    <parameters>
      <parameter name="assemblyName" value="${include.coverage.assembly}" />
      <parameter name="moduleCompany" value="${module.company}" />
      <parameter name="generatedOn" value="${coverage.report.generation.datetime}" />
      <parameter name="coverageBaseline" value="${coverage.baseline}" />
    </parameters>
  </style>
</target>

3. Generating Coverage Summary Index Page:
Also, the way our project components are structured, we perform a top-level build (at solution level) and an individual component level build (at project level), we needed a way to summarize the coverage reports for all the components (as well as at component level => project level) when we do a top-level build. To that end, I ended up creating a index.html that would generate the summary report and serve as an entry point to drill-down to individual assemblies for detail coverage report by class within that assembly. Here is the NAnt target to achieve that (In reality, this task is present in a different build file, but I have shown this as inlined here).

<target name="generate.coverage.reports.index" depends="generate.coverage.report" description="Prepare Index.html for all coverage reports">
  <copy file="${coverage.report.css.file}" todir="${root.dir}${coverage.reports.dir.root}" />
  <property name="index.file" value="${root.dir}${coverage.reports.dir.root}${index.file.name}" dynamic="true" />
  <echo file="${index.file}">
    <![CDATA[
	<html>
	  <head>
            <title>[SOLUTION NAME] Coverage Reports</title>
            <link rel="stylesheet" type="text/css" href="coverage-report.css" />
	  </head>
	  <body>
 	    <h1><center>[SOLUTION NAME] Code Coverage Reports</center></h1>
	    <center>Generated on: ${coverage.report.generation.datetime} IST.</center>
	    <hr size="1"/>
	    <p>
	    This coverage report contains all code coverage statistics. Current Code Coverage Percentage Baseline is: <b>${coverage.baseline}%</b>.  Code Coverage below this baseline is not acceptable.
	    <table>
	      <tr>
		<th class="TableHeader">Legend</th>
	      </tr>
	      <tr>
		<td class="cov0style">0%</td>
	      </tr>
	      <tr>
		<td class="cov20style">0%-19%</td>
	      </tr>
	      <tr>
		<td class="cov40style">20%-39%</td>
	      </tr>
	      <tr>
		<td class="cov60style">40%-59%</td>
	      </tr>
	      <tr>
		<td class="cov80style">60%-79%</td>
	      </tr>
	      <tr>
		<td class="cov100style">80%-100%</td>
	      </tr>
	   </table>
         </p>

         <h2>Assemblies Summary</h2>
	 <table border="0" cellpadding="2" cellspacing="0" width="60%" style="border: #dcdcdc 1px solid;">
	 <tr class=TableHeader><td>Assembly Name</td><td>Coverage (%)</td></tr>
    ]]>
  </echo>
  <foreach item="File" in="${root.dir}${coverage.reports.dir.root}" property="fileNameWithPath">
    <property name="fileNameWithExtn" value="${path::get-file-name(fileNameWithPath)}" />
    <if test="${not (string::starts-with(fileNameWithExtn, index.file.name)
                            or string::starts-with(fileNameWithExtn, coverage.report.css.file.name))}">
      <property name="fileName" value="${path::get-file-name-without-extension(fileNameWithPath)}" />
      <property name="displayFileName" value="${string::replace(fileName, coverage.result.file.prefix, '')}" />
      <loadfile file="${fileNameWithPath}" property="coverageFileContent" />
      <property name="start.position" value="${string::index-of(coverageFileContent, '~~') + 2}" />
      <property name="length" value="${string::last-index-of(coverageFileContent, '~~') - int::parse(start.position)}" />
      <property name="assembly.coverage.percentage" value="${string::substring(coverageFileContent, start.position, length)}"/>
      <echo file="${index.file}" append="true">
         <![CDATA[
          <tr></a></td>
	  <td><span class="
	 ]]>
      </echo>
      <if test="${int::parse(assembly.coverage.percentage) == 0}">
        <echo file="${index.file}" append="true">
          <![CDATA[cov0style]]>
          </echo>
      </if>
      <if test="${int::parse(assembly.coverage.percentage) >= 1 and (int::parse(assembly.coverage.percentage) < 20)}">
        <echo file="${index.file}" append="true">
          <![CDATA[cov20style]]>
          </echo>
      </if>
      <if test="${int::parse(assembly.coverage.percentage) >= 20 and (int::parse(assembly.coverage.percentage) < 40)}">
        <echo file="${index.file}" append="true">
          <![CDATA[cov40style]]>
          </echo>
      </if>
      <if test="${int::parse(assembly.coverage.percentage) >= 40 and (int::parse(assembly.coverage.percentage) < 60)}">
        <echo file="${index.file}" append="true">
	  <![CDATA[cov60style]]>
	  </echo>
        </if>
      <if test="${int::parse(assembly.coverage.percentage) >= 60 and (int::parse(assembly.coverage.percentage) < 80)}">
        <echo file="${index.file}" append="true">
	  <![CDATA[cov80style]]>
	  </echo>
      </if>
     <if test="${int::parse(assembly.coverage.percentage) >= 80 and (int::parse(assembly.coverage.percentage) <= 100)}">
      <echo file="${index.file}" append="true">
        <![CDATA[cov100style]]>
      </echo>
    </if>

    <echo file="${index.file}" append="true">
        <![CDATA[
	  " style="width:100%">${assembly.coverage.percentage}</span></td></tr>
        ]]>
      </echo>
    </if>
  </foreach>

  <echo file="${index.file}" append="true">
    <![CDATA[
      </table>
      <hr size="1"/>
      &copy; ${module.company}
      </body>
      </html>
    ]]>
  </echo>
</target>

4. Failing the Build:
Also, we want to fail the build when the coverage falls below a desired level. To that end, I created a simple target that would fail the build incase actual coverage was less than the expected coverage baseline.

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Taking DDD Concept of Entity just a bit further

27 Friday Mar 2009

Posted by Dhaval Dalal in C#

≈ Leave a comment


It would be difficult to find enterprise projects that do not talk to other systems (external or internal), unless yours is an application that is purely a sourcing system or is a system that is independently catering to a small audience or a department. On my current project, we are talking to other internal systems within the enterprise and need to store references to entities inside external systems within our system. To be more precise, this storing boils down to two cases:

  1. Storing the reference to an external entity. An example would be all Country or State related information being managed in an external system and we need to store reference to the country/state, in this case we store only the id of the country (not the surrogate id, but countryCode which becomes a symbol that uniquely identifies a country or state within a country).
  2. Storing few concerned attributes along with external reference. An example, would be storing price details of an Item along with UPC (Universal Product Code), because price keeps on changing and we need to reflect the price that was applied at the time the transaction was created.

In either of the above cases, at minimum, we need to store reference to that external entity. As we need to express external entity as a part of our model, we end up creating an abstraction for it in our system. We should note the following characteristics of such an external entity:

  1. We never manage the life-cycle of an external entity.
  2. Hence it is implied that we never assign Id to an external entity.
  3. We use these entities in Read-Only Mode and usually query for these entities by criteria.

In an effort to make this distinction clear in the model, I extended the DDD Entities concept by classifying Entities as Internal Entity and External Entity.

  1. Internal Entity – Any object whose life-cycle is managed within our module/project is an Internal Entity.
  2. External Entity – Any object whose life-cycle is not managed within our module/project, but only store references (ocassionally along with few attributes) to those entities is an External Entity.

A sample implementation of such a classification could be rendered with simple interface based static hierarchy or you could choose to use Annotations (in Java)/Attributes (in C#) to achieve this classification. Below is a sample implementation using marker interfaces and abstract classes in C#.

public interface Entity
{
}
  1. Internal Entity Implementation – Mark Internal entities with a marker interface InternalEntity or you can have an abstract class InternalEntity. Surrogate Id generation is taken care-of within this and so is identity based equality implementation.
    // Any entity whose life-cycle is controlled by our project/module is an Internal Entity and hence we
    // assign a surrogate Id to our entities and hence this is manifested as "id" field in this abstract class. All
    // our internal entities will derive from this class.
    public abstract class InternalEntity : Entity
    {
      private int id;
    
      public virtual int Id
      {
        get { return id; }
        private set { id = value; }
      }
    
      public override string ToString()
      {
        return GetType().Name + " Id = " + id;
      }
    
      public override bool Equals(object obj)
      {
        if (ReferenceEquals(obj, null))
        {
          return false;
        }
        if (ReferenceEquals(obj, this))
        {
          return true;
        }
        if (this.GetType() != typeof(obj))
        {
          return false;
        }
        InternalEntity that = (InternalEntity) obj;
        return (Id == that.Id);
      }
    
      public override int GetHashCode()
      {
        return id.GetHashCode();
      }
    }
    

  2. External Entity Implementation – Mark all External entities with a marker interface ExternalEntity. We cannot provide a common behavior as we do not know the primary keys that will uniquely identify this entity.
    // Any entity whose life-cycle is not controlled within our module/project is an external entity for us.
    // Hence, any reference that we need to store in our module/project for external entities should
    // be assigned by the classes implementing this interface.
    public interface ExternalEntity : Entity
    {
    }
    

Having applied this on my project, I found that this segregation has following positive side-effect:

  1. Developers while doing analysis can quickly discern which entities are internal or external to the system.
  2. Helps improve code readability.
  3. While writing services that we use for querying these external entities, we have been able to treat that external persistent store as a xxxQueryRepositoryService. For example, we could then have model layer services like the ICountryQueryRepositoryService or IItemQueryRepositoryService. Again, the implementation could talk to the external system via a Remote Method call or a Web service call, is completely shielded from clients…essentially, still maintaining Persistence Ignorance in spirit.
  4. We continue to apply the repository pattern to internal entities, by using xxxRepository. For example, we can have IPurchaseOrderRepository

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

NHibernate IMultiQuery and IMultiCriteria support beats Hibernate

15 Sunday Mar 2009

Posted by Dhaval Dalal in C#

≈ Leave a comment


When I started implementing a generic Pagination solution on my current project that uses NHibernate, like before (largely due to my experience with Hibernate in Java), where I have always fired two Hql/Criteria queries to implement this feature.

  1. To get total count of all the records.
  2. To get the actual page from the database using the session.setFirstResult() and setMaxResults()

However, with NHibernate, I happen to see the CreateMultiCriteria() and CreateMultiQuery() on session Api, and started reading about IMultiCriteria and IMultiQuery. NHibernate introduced IMultiCriteria and IMultiQuery that targets at executing multiple queries in a single trip to the database server. In the above case, the two trips (one for each query) to the database will be now fired in a single shot operation. This is really good and can improve performance. I wish this Api can become part of Hibernate (last I used was 3.2), if it is not. Here is the code snippet that shows the use of IMulticriteria Api.

private Page<T> CreatePage(int pageNumber, int pageSize)
{
  ICriteria criteria =  session.CreateCriteria(typeof(T))
                .SetFirstResult(pageSize*(pageNumber - 1))
                .SetMaxResults(pageSize);

  ICriteria criteriaForTotalRecords = session.CreateCriteria(typeof(T))
                 .SetProjection(Projections.RowCount());

  IList resultSet = GetSession().CreateMultiCriteria()
                .Add(criteria)
                .Add(criteriaForTotalRecords)
                .List();

  IList pageWithRecords = (IList)resultSet[0];
  IList<T> records = Convert.ToGenericList<T>(pageWithRecords);
  int totalRecordsInAllPages = (int)((IList)resultSet[1])[0];
  return new Page<T>(records, totalRecordsInAllPages, pageNumber, pageSize);
}

At the same time, please note that the IMultiQuery.List() method unlike, IQuery does not return a Generic List and so I ended up creating a utility class, which in my case I chose to call it Convert, has a operation ToGenericList<T>(), which you will need often from other queries as well. Here is the code for that class.

public static class Convert
{
  public static IList<T> ToGenericList<T>(IList items)
  {
    IList<T> genericList = new List<T>(items.Count);
    foreach (T item in items)
    {
      genericList.Add(item);
    }
    return genericList;
  }
}

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...

Using Dynamic Filter in NHibernate and Problems I encountered while using it

14 Saturday Mar 2009

Posted by Dhaval Dalal in C#

≈ Leave a comment


I ran into this situation where dynamic filter came to the rescue on my current project using NHibernate. Also, I have posted herein the problem that I faced after I implemented dynamic filter and how I solved it. In summary, I have used the NHibernate dynamic filter to filter out children of an aggregate based on a criteria. If you have another approach do drop your solution in the comments below.

The Context:
We have our own product related schema and another legacy schema to talk to using NHibernate. As usual, Legacy tables have composite keys whereas we use surrogate keys for our tables. So, all the querying to legacy tables is using composite keys (as we are not allowed to modify the table schema because the team that manages legacy fears that stored procs and other stuff would break). Now, we need to query for unique UserInfo object (this object maps to legacy table) to determine whether the user is authorized to access a particular module or not. In our case, we are following DDD (Domain Driven Design) approach and have UserInfo as an Aggregate that has UserRights. Thus, there is a one-to-many relationship of UserInfo to UserRight. The UserRight contains the specific right the user has for a Module (another Aggregate).

There are typically two scenarios that require us to query the legacy tables to get UserRights:

  1. We want to know all the rights a user has for all the modules.
  2. We want to know all the rights a user has for a particular module.

For #1, it means that the UserRight property on the UserInfo should return all the UserRight instances for all the modules that the user has access rights defined, whereas for #2 it means that the UserRight property should filter-out non-required modules and should have only UserRight instances for the desired module. This way the client gets what they want and do not have to worry about filtering.

Next, We define a service that is a stand-in for the client and will serve the above two scenarios by implementing the two operations as shown in the IUserInfoRepositoryService (one repository-per-aggregate) below:

public interface IUserInfoRepositoryService
{
  UserInfo FindUniqueBy(string userId);
  UserInfo FindUniqueBy(string userId, ModuleId moduleId);
}

Here are the tests that cater to the two scenarios. HibernateUserInfoRepositoryService is an implementation of IUserInfoRepositoryService and below is the test for that conrete implementation.

[TestFixture, Category(TestType.Database)]
public class HibernateUserInfoRepositoryServiceTest : RequiresDatabaseTestSupport
{
  private const string userId = " TEST USER";
  // set up and other data

  // other tests...
  // ...
  // ...

  [Test ("That I wrote first") ]
  public void ShouldFindUniqueUserByUserIdContainingAllModuleRights()
  {
      HibernateUserInfoRepositoryService hibernateUserInfoRepositoryService = new HibernateUserInfoRepositoryService(SessionFactory);
      UserInfo userInfo = hibernateUserInfoRepositoryService.FindUniqueBy(userId);
      Assert.That(userInfo.UserRights, Is.Not.Empty);
      Assert.That(userInfo.UserRights, Has.Member(chargeModuleViewRight);
      Assert.That(userInfo.UserRights, Has.Member(chargeModulePrintRight);
      Assert.That(userInfo.UserRights, Has.Member(accModuleAddRight);
      Assert.That(userInfo.UserRights, Has.Member(accModuleViewRight);
  }

  [Test ("That I wrote second") ]
  public void ShouldFindUniqueUserByUserAndModuleIdsWithModuleRights()
  {
    HibernateUserInfoRepositoryService hibernateUserInfoRepositoryService = new HibernateUserInfoRepositoryService(SessionFactory);
    ModuleId accModuleId = MakeNew.ModuleId
                .WithId(3002)
                .WithType("ACC")
                .Build();

    UserInfo userInfo = hibernateUserInfoRepositoryService.FindUniqueBy(userId, accModuleId);
    Assert.That(userInfo.UserRights, Is.Not.Empty);
    Assert.That(userInfo.UserRights.Count, Is.EqualTo(2));
    Assert.That(userInfo.UserRights, Has.Member(accModuleAddRight);
    Assert.That(userInfo.UserRights, Has.Member(accModuleViewRight);
    Assert.That(userInfo.UserRightsAsAccessRight, Is.EqualTo(AccessRight.Add | AccessRight.View));
  }
}

Here is the UserInfo class:

public class UserInfo
{
  private readonly string id;
  private readonly string name;
  private readonly bool enabled;
  private readonly ISet<UserRight> userRights = new HashedSet<UserRight>();

  public static UserInfo Empty = new UserInfo();

  [Obsolete("For NHibernate Use Only, use CreateNew() instead")]
  protected UserInfo()
  {
  }

  [Obsolete("Never make this public, use CreateNew() instead")]
  private UserInfo(string id, string name, bool enabled, ISet<UserRight> userRights)
  {
    this.id = id;
    this.name = name;
    this.enabled = enabled;
    this.userRights = userRights;
  }

  public virtual string Id
  {
    get { return id; }
  }

  public virtual bool IsEnabled
  {
    get { return enabled; }
  }

  public virtual string Name
  {
    get { return name; }
  }

  public virtual ISet<UserRight> UserRights
  {
    get { return userRights; }
  }

  // Other Equality and HashCode methods

  public static UserInfo Create(string userId, string name, bool enabled, ISet<UserRight> userRights)
  {
    return new UserInfo(userId, name, enabled, userRights);
  }
}

So far so good, next we need to focus on the mapping for this class. If you have static where clause in the NHibernate mapping, it does no good. Tackling this kind of situation demands the use of a dynamic filter, so that we can choose when to apply it and when not to. NHibernate allows you to define Filters using the <filter-def> tag. Take a look at the UserInfo.hbm.xml below. We have defined a filter by name filterUserRightsByModuleId that takes in moduleId and moduleType as a parameter. These two together happen to be in our case the composite-key for accessing a Module. This filter is used by the userRights set definition, this is exactly how the filter is applied. We define the filtering condition on the filter-instance where it is used. Now, this sets-up the filter for use.

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="Company.Model.User" assembly="Some.Assembly" default-access="field.camelcase" xmlns="urn:nhibernate-mapping-2.2">
  <class name="UserInfo" table="User" mutable="false">
    <id name="id" column="RID" type="string">
      <generator class="assigned"/>
    </id>
    <property name="Enabled" column="Enabled" type="yes_no" />
    <property name="Name" column="Name" type="string" />
    <set name="userRights" table="User_Access">
      <key column="RID"/>
      <one-to-many class="UserRight"/>
      <filter name="filterUserRightsByModuleId" condition="moduleId = :moduleId and moduleType = :moduleType">
      </filter>
    </set>
  </class>
  <filter-def name="filterUserRightsByModuleId">
    <filter-param name="moduleId" type="int"/>
    <filter-param name="moduleType" type="string"/>
  </filter-def>
</hibernate-mapping>

Before I show how to use the filter, take a look at the UserRight Class and its NHibernate Mapping below:

public class UserRight
{
  public static readonly UserRight Empty = new UserRight();
  private int id;
  private readonly UserInfo userInfo;
  private readonly Module module;
  private readonly string value;

  [Obsolete("For NHibernate use only, Use CreateNew() Instead.")]
  protected UserRight()
  {
  }

  [Obsolete("Never make this public, Use CreateNew() Instead.")]
  private UserRight(UserInfo userInfo, Module module, string value)
  {
      this.userInfo = userInfo;
      this.module = module;
      this.value = value;
  }

  public virtual int Id
  {
      get { return id; }
  }

  public virtual AccessRight AccessRight
  {
      get
      {
          try
          {
              return (AccessRight) Enum.Parse(typeof(AccessRight), value, true);
          }
          catch (ArgumentException)
          {
              return AccessRight.None;
          }
      }
  }

  public virtual UserInfo UserInfo
  {
      get { return userInfo; }
  }

  public virtual Module Module
  {
      get { return module; }
  }

  // Other Equality and HashCode methods

  public static UserRight CreateNew(UserInfo userInfo, Module module, string value)
  {
      return new UserRight(userInfo, module, value);
  }
}

Here is UserRight.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="Company.Model.User" assembly="Some.Assembly" default-access="field.camelcase" xmlns="urn:nhibernate-mapping-2.2">
  <class name="UserRight" table="User_Access" mutable="false">
    <id name="id" column="ID" type="int">
      <generator class="assigned"/>
    </id>
    <many-to-one name="userInfo" column="RID" class="UserInfo"/>
    <many-to-one name="module" class="Company.Model.Authorization.Module" lazy="proxy">
      <column name="ModuleType" />
      <column name="ModuleId" />
    </many-to-one>
    <property name="Value" column="Activity" type="string" />
  </class>
</hibernate-mapping>

As I started TDDing, I implemented the first test that was quite straight forward and resulted in creating a Criteria query with a simple Equal restriction. When I wrote the second test, I introduced the filter in the mapping file and the corresponding code in the repository implementation that would enable the filter using the session.EnableFilter() , set the filter parameters (which get substituted in the filter condition upon query execution), and finally validate the filter and fire the query. The filter remains enabled for the session until you explicitly call session.DisableFilter(). Below is the Implementation of that repository code.

public class HibernateUserInfoRepositoryService : IUserInfoRepositoryService
{
  public HibernateUserInfoRepositoryService(ISessionFactory sessionFactory)
  {
       //...
       //...
  }

  public UserInfo FindUniqueBy(string userId)
  {
    return FindUniqueBy(userId, null);
  }

  public UserInfo FindUniqueBy(string userId, ModuleId moduleId)
  {
    ISession session = GetSession();
    if (moduleId != null)
    {
      IFilter filter = session.EnableFilter("filterUserRightsByModuleId");
      filter.SetParameter("moduleId", moduleId.Id);
      filter.SetParameter("moduleType", moduleId.Type);
      filter.Validate();
    }
    else
    {
      session.DisableFilter("filterUserRightsByModuleId");
    }

    ICriteria criteria = session.CreateCriteria(typeof (UserInfo));
    criteria.Add(Restrictions.Eq("id", userId));
    UserInfo userInfo = criteria.UniqueResult() as UserInfo;
    if (userInfo == null)
    {
      return UserInfo.Empty;
    }
    return userInfo;
  }
}

Everything looked nice, and I ran the second test…a green bar.

The Problem:

Next, I ran the all the tests in the fixture and to my surprise, I got a red bar from my second test. This left me a bit puzzeled…why the hell the second test is failing!?! I turned show_sql On and found that NHibernate was correctly issuing the query by substituting the parameters from the filter and applying it to “where” clause in the generated Sql. I then decided to run just the second test individually and I saw it pass. This means something really interesting was going on there…I learnt that when I ran all the tests NHibernate was caching the UserRights from the earlier test run. Hmmm, so found the problem!

To help you understand my testing context further, I need to share the way in which we have written our DatabaseTestSupport infra-structure code.

  1. Every test runs within a transaction and at the end of the test, the transaction is rolled back.
  2. We use the same session that was created before the start of the first test and also clear the session (by calling session.Clear()) after each test. session.Clear() evicts all loaded instances, and cancels all pending saves, updates and deletes.

Now, UserInfo, UserRight are entities that are always queried for and causes NH to cache these objects and return the same ones from the cache and hence the second test fails despite clearing the session and rolling back transaction after each test.


A Solution:

This scenario can occur in real-life when calls are made to FindUniqueBy(string userId) and FindUniqueBy(string userId, ModuleId moduleId), within same session. The solution to this that I need to force a reload from database for that entity each time so that earlier “many” side of association is retrieved again from DB and not cache, giving me the expected results. This is where ISession.Refresh() comes to the help. Here is how I used it and solved the problem that I faced.

public class HibernateUserInfoRepositoryService .....
{
  //...
  //...

  public UserInfo FindUniqueBy(string userId, ModuleId moduleId)
  {
    ISession session = GetSession();
    if (moduleId != null)
    {
      IFilter filter = session.EnableFilter("filterUserRightsByModuleId");
      filter.SetParameter("moduleId", moduleId.Id);
      filter.SetParameter("moduleType", moduleId.Type);
      filter.Validate();
    }
    else
    {
      session.DisableFilter("filterUserRightsByModuleId");
    }

    ICriteria criteria = session.CreateCriteria(typeof (UserInfo));
    criteria.Add(Restrictions.Eq("id", userId));
    UserInfo userInfo = criteria.UniqueResult() as UserInfo;
    if (userInfo == null)
    {
      return UserInfo.Empty;
    }
    ForceReloadFromDatabase(userInfo);
    return userInfo;
  }

  private void ForceReloadFromDatabase(object entity)
  {
    GetSession().Refresh(entity);
  }
}

Finally, Green bar for all the tests!

Share this:

  • Twitter
  • LinkedIn
  • Google
  • Reddit
  • Email
  • Facebook
  • Print

Like this:

Like Loading...
← Older posts

Dhaval Dalal

Profile

Dhaval Dalal

Slides

View DhavalDalal's profile on slideshare

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 290 other followers

Ideas

  • Code Jugalbandi

Open Source Projects

  • Java8 Exception Monad
  • Midas
  • Tayra

Recent Posts

  • Exploring Concurrency CodeJugalbandi February 6, 2019
  • Destructuring and Pattern Matching in Functional Programming December 29, 2018
  • Help yourself by making iTerm2 vivid May 30, 2018
  • How to disable failed discrete-GPU (NVIDIA GeForce GT 650M) for 15″ MacBook-Pro 10,1 (mid-2012) on High Sierra 10.13.4 May 29, 2018
  • Improvised Tasks.tmbundle for TextMate April 15, 2018

Calendar

February 2019
M T W T F S S
« Dec    
 123
45678910
11121314151617
18192021222324
25262728  

Categories

  • Agile (13)
  • APL (2)
  • Array-Oriented (1)
  • C# (14)
  • Clojure (2)
  • Code Jugalbandi (5)
  • Code Retreat (2)
  • Computer (2)
  • Education (1)
  • Erlang (3)
  • Functional Programming (10)
  • Functional Reactive (3)
  • General (34)
  • Groovy (15)
  • GWT (6)
  • Haskell (2)
  • Java (28)
  • JavaScript (10)
  • Life (2)
  • Microservices (1)
  • MongoDB (2)
  • Music (2)
  • Neo4J (1)
  • Sanskrit (4)
  • Scala (8)
  • Thoughts-Philosophy (9)
  • Yoga (2)

Archives

Follow me on Twitter

My Tweets

Blog Stats

  • 26,700 hits

Tags

Agile Code Jugalbandi Erlang Functional Programming General Groovy Homeopathy iTerm2 java Java8 Life Microservices reactjs rxjs Sanskrit Scala Textmate2 Thoughts-Philosophy

RSS

  • RSS - Posts
  • RSS - Comments
Advertisements

Blog at WordPress.com.

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy
%d bloggers like this: