Archive for the ‘Programming’ Category

Testing DateTime.Now

Monday, February 1st, 2010

When you are doing Test Driven Development (TDD) many time during the testing phase you’ll find yourself with a code that depends on current time.

It’s not possible write tests for this code as DateTime.Now changes constantly.

Let’s take a look at following method:

public string CreateName(...)
{
   return "name " + DateTime.Now;
}

The solution to this problem is simple. We’ll introduce Clock class with the same interface as DateTime:

public string CreateName(...)
{
   return "name " + Clock.Now;
}

We’d like the test to look something like this:

[Test]
public void CreateName_AddsCurrentTimeAtEnd()
{
    using (Clock.NowIs(new DateTime(2010, 12, 31, 23, 59, 00)))
    {
        string name = new ReportNameService().CreateName(...);
        Assert.AreEqual("name 2010-12-31 23:59:00", name);
    }
}

Tests should not leave any side effects. This is why we are using IDisposable pattern. After text execution Clock.Now is reverted and again returns current time.

Finally this is how Clock class looks like:

public class Clock : IDisposable
{
    private static DateTime? _nowForTest;

    public static DateTime Now
    {
        get { return _nowForTest ?? DateTime.Now; }
    }

    public static IDisposable NowIs(DateTime dateTime)
    {
        _nowForTest = dateTime;
        return new Clock();
    }

    public void Dispose()
    {
        _nowForTest = null;
    }
};

Cross-thread operations with PostSharp

Tuesday, January 26th, 2010

When you try to inform User Interface (UI) about the background operation progress or completion, you can not do it from the background thread.

UI doesn’t like to be informed about anything from a different thread: you’ll get “System.InvalidOperationException: Cross-thread operation not valid: Control ‘xxx’ accessed from a thread other than the thread it was created on.” exception from WinForms control, if you try:

public void ShowStatus(ApplicationStatus status)
{
    this._lblServiceAddress.Text = "Connected to: "
        + status.WebServiceAddress;
    this._lblUserId.Text = "Working as: "
        + status.UserId;
}

The easiest sollution is to use BeginInvoke method on the control Control or Form:

public void ShowStatus(ApplicationStatus status)
{
    this.BeginInvoke((MethodInvoker)(() =>
        {
            this._lblServiceAddress.Text = "Connected to: "
                + status.WebServiceAddress;
            this._lblUserId.Text = "Working as: "
                + status.UserId;
        }));
}

Well, it’s fun to write this once, but if you have many operations done in background sooner or later you’d like to have something nicer. Like an attribute for example:

[ThreadAccessibleUI]
public void ShowStatus(ApplicationStatus status)
{
    this._lblServiceAddress.Text = "Connected to: " + status.WebServiceAddress;
    this._lblUserId.Text = "Working as: " + status.UserId;
}

Here’s the attribute implementation of such attribute using PostSharp 1.5:

/// <summary>
/// PostSharp attribute.
/// Use it to mark Control's methods that
/// are invoked from background thread.
/// </summary>
/// <remarks>
/// Be careful as BeginInvoke uses the message queue.
/// This means that the interface will be refreshed
/// when application has a chance to process its messages.
/// </remarks>
[AttributeUsage(AttributeTargets.Method)]
[Serializable] // required by PostSharp
public class ThreadAccessibleUIAttribute : OnMethodInvocationAspect
{
    public override void OnInvocation(
        MethodInvocationEventArgs eventArgs)
    {
        Control control = eventArgs.Instance as Control;
        if (control == null)
            throw new ApplicationException(
                "ThreadAccessibleUIAttribute" +
                "can be applied only to methods on Control class");

        // The form may be closed before
        // this method is called from another thread.
        if (control.Created == false)
            return;

        control.BeginInvoke((MethodInvoker)eventArgs.Proceed);
    }
};

FindAll, ConvertAll are your friends

Wednesday, January 6th, 2010

Let’s take a look at following code:

public List<string> GetDeleteWarnings_ForEach()
{
    List<string> messages = new List<string>();
    foreach (ItemReference reference in _itemReferences)
    {
        if (!reference.CanBeDeleted)
        {
            messages.Add(reference.DeleteMessage);
        }
    }
    return messages;
}

Using FindAll and ConvertAll you can do it in one, very obvious, line:

public List<string> GetDeleteWarnings_Fluently()
{
    return _itemReferences
        .FindAll(x => !x.CanBeDeleted)
        .ConvertAll(x => x.DeleteMessage);
}

Dictionary: SerializationException

Wednesday, December 30th, 2009

When you to inherit your custom dictionary from Dictionary class you’ll get nasty exception during deserialization:

System.Runtime.Serialization.SerializationException : The constructor to deserialize an object of type ‘SafeDictionary`2[System.String,System.String]‘ was not found.

[Serializable]
internal class SafeDictionary<K, V> : Dictionary<K, V>
{
    public new V this[K key]
    {
            get
            {
                V value;
                if (this.TryGetValue(key, out value) == true)
                    return value;
                return default(V);
            }
            set
            {
                base[key] = value;
            }
    }

     public SafeDictionary()
    {
    }
};

Here’s the test:

[Test]
public void IsSerializable()
{
    SafeDictionary<string,string> dictionary =
        new SafeDictionary<string, string>();
    dictionary["key"] = "value";
    dictionary =
        SerializationHelper.SerializeAndDeserialize(dictionary);
    Assert.AreEqual("value", dictionary["key"]);
}

And serialization utility class:

class SerializationHelper
{
    public static T SerializeAndDeserialize<T>(T sm)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        using (MemoryStream stream = new MemoryStream())
        {
            formatter.Serialize(stream, sm);
            stream.Position = 0;
            return (T)formatter.Deserialize(stream);
        }
    }
}

Dictionary class implements ISerializable interface.

The ISerializable interface implies a constructor with the signature constructor (SerializationInfo information, StreamingContext context).

At deserialization time, the current constructor is called only after the data in the SerializationInfo has been deserialized by the formatter. In general, this constructor should be protected if the class is not sealed.

So what you need to do is to add the following constructor:

    //Needed for deserialization.
    protected SafeDictionary(SerializationInfo information, StreamingContext context)
            : base(information,context)
    {
    }

Now the test will pass.

NHibernate ignores SetMaxResults in SQL

Tuesday, December 8th, 2009

nhibernateRecently me and my team realized that several our queries, that include maximum limit on the recordset, are limited in the web application and not on the Oracle side.

First thought was that somebody simply forgot to add an invocation of SetMaxResults method, but our repository code was very obvious about it:

IQuery query = session.CreateQuery(hqlQuery);
query.SetMaxResults(100);

After some investigation it turned out that NHiberante is not able to use ROWNUM on the SQL side, when there is a fetch join on the collection.

EmployeeDatas

This is HQL query we use:

select
    user
from
    User user
    /* next line causes no rownum check */
    inner join fetch user.EmployeeDatas EmployeeData
    left join fetch EmployeeData.Country country

And some NHibernate code:

public IList List(ISessionImplementor session, QueryParameters queryParameters)
{
	// ...
	if ( hasLimit && ContainsCollectionFetches )
	{
		log.Warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );

NHibernate simply ignores the limit when executing the query and applies it on the result.

At some point I thought that it is not possible to even create such SQL query, but I was proven to be wrong. The query would look similar to this proof-of-concept:

SELECT
	   *
FROM
(
 	SELECT
		   *
    FROM
		 TUSER u
	WHERE
		  /* Add conditions here: */
		  EXISTS(...)
		  /* Here is DB-side limit: */
 		  AND ROWNUM <= 14
) AS u
/* And now fetch all collections needed */
INNER JOIN TEMPLOYEEDATA d ON u.ID = d.USERID

So it’s clear that it is possible to improve this in NHibernate.

In our case change was simple:
We changed one-to-many mapping to one-to-one.

But if you are not able to do this because of your requirements I would use custom SQL view and mapped it in NHibernate. The second idea would be to use NHibernate detached criteria and sub-queries.

Finally the unit test that we used to check if the limit is done on SQL database side:

[Test]
public void FindUsersBy_QueryWithLimit_LimitsOnSQLSide()
{
    using (LogChecker logChecker = new LogChecker("NHibernate", Level.Warn))
    {
        IList<User> users = this._context.ExecuteInTransaction(() =>
        {
            UserQuery q = new UserQuery();
            q.UserId = "ILMT";
            q.MaxNumberOfRecords = 14;
            return this._context.UserRepository.FindUsersBy(q);
        });
        Assert.IsEmpty(logChecker.Messages);
        Assert.AreEqual(14, users.Count);
    }
}

Here you can see the implementation of the LogChecker log4net log reader