24 August 2006

Finally it is true!

Yesterday, PFC Levski Sofia did it. The team had succeeded to qualify for the UEFA champions league group stage for the first time in Bulgarian football history. Although I'm fan of the CSKA Sofia the success of Levski makes me happy. More info - here.

23 August 2006

Microsoft SQL Server and Ad-Hock queries optimization

Yesterday I was surprised to learn that Microsoft SQL Server 2005 makes behind the scene parameterization of ad-hock queries. For example, lets have the following query:
SELECT ID, Name FROM Article WHERE Price > 100

SQL Server 2005 will replace constant literal values (100 in this example) by variables and this way query plan will be reuses for all queries similar to
SELECT ID, Name FROM Article WHERE Price > @p1

Not all of the ad-hock queries can be parameterized. If you are interested read this article.

Attribute based transaction management and NHibernate

In my previous post about NHibernate session management I presented a session per request strategy for session management in ASP.NET application. I will extend this example to show you how to declaratively manage transactions via attributes. Take a look at the GenericDAO.Save method:

public void Save(T entity)
{
    bool manageTransaction = ! orm.isActiveTransaction;
    if (manageTransaction)
    {
        orm.BeginTransaction(IsolationLevel.ReadCommitted);
    }
    try
    {
        orm.session.SaveOrUpdate(entity);
 
        if (manageTransaction)
        {
            orm.CommitTransaction();
        }
    }catch(Exception e)
    {
        if (manageTransaction)
        {
            orm.RollbackTransaction();
        }
 
        throw e;
    }            
}

Almost 90% of the code is for transaction management. It will be nice if we can write something like:

[Transaction(IsolationLevel.ReadCommitted)]
public void Save(T entity)
{
    mOrm.session.SaveOrUpdate(entity);
    mOrm.session.Flush();
}

To achieve this, I will use Spring.NET to intercept method call of the DAO. Before method marked with TransactionAttribute is executed a transaction will be started and then committed after method is executed. Although .NET provides solution for intercepting method calls via ContextBoundObject, I will use Spring.NET because this way my DAO object must implement just one interface instead of inheriting from ContextBoundObject.
Lets begin with the implementation. First I will declare the attribute used to mark transaction sensitive methods:

[AttributeUsage(AttributeTargets.Method)]
public class TransactionAttribute : Attribute
{
    private IsolationLevel mIsolationLevel;
 
    public TransactionAttribute()
    {
        mIsolationLevel = IsolationLevel.ReadCommitted;
    }
 
    public TransactionAttribute(IsolationLevel aIsolation)
    {
        mIsolationLevel = aIsolation;
    }
 
    public IsolationLevel isolationLevel
    {
        get { return mIsolationLevel; }
        set { mIsolationLevel = value; }
    }
 
}

Now I will decrare the class responsible for starting and committing transactions. There are a lot of specific issues about method interception and Spring.NET so if you are not familiar with them read the documentation about Spring.NET. The class looks like:

public class TransactionAroundAdvice : IMethodInterceptor
{
    OrmManager mOrm;
 
    public TransactionAroundAdvice()
    {
        mOrm = OrmManagerFactory.GetInstance();
    }
 
    private TransactionAttribute GetTransactionAttribute(MethodInfo aMethod)
    {
        object[] attributes = aMethod.GetCustomAttributes(
            typeof(TransactionAttribute), true);
 
        if (attributes.Length != 1)
        {
            //TODO: Throw more meaningfull exception and message
            throw new Exception("Transaction Attribute is missing");
        }
        return (TransactionAttribute)attributes[0];
    }
 
    public object Invoke(IMethodInvocation invocation)
    {
        bool manageTransaction = ! mOrm.isActiveTransaction;
        if (manageTransaction)
        {
            TransactionAttribute transactionAttribute =
                GetTransactionAttribute(invocation.Method);
            mOrm.BeginTransaction(transactionAttribute.isolationLevel);
        }
 
        //TODO: Find way to compare isolation level from TransactionAttribute and
        //current active transaction if manageTransaction == false
 
        object returnValue;
        try
        {
            returnValue = invocation.Proceed();
 
            if (manageTransaction)
            {
                mOrm.CommitTransaction();
            }
        }catch(Exception e)
        {
            if (manageTransaction)
            {
                mOrm.RollbackTransaction();
            }
 
            if ((e is TargetInvocationException) && (e.InnerException != null))
            {
                //Because when AOP is enables, method is invoked via reflection
                //TargetInvocationException is thrown. This exception is most likely
                //to confuse application developer, so it is removed
                throw e.InnerException;
            }
            else
            {
                throw e;
            }
        }            
 
        return returnValue;
    }
}

When a method marked with TransactionAttribute is intercepted then Invoke method from TransactionAroundAdvice class is called. Now lets see how our DAO class looks like when transaction management code is removed:

public class AttributeEnabledDAO<T>: IDAO<T>
{
    public AttributeEnabledDAO()
    {
        mOrm = OrmManagerFactory.GetInstance();
    }
 
    private OrmManager mOrm;
 
    #region IDAO Members
 
    public T Load(object id)
    {
        return (T) mOrm.session.Load(typeof(T), id);
    }
 
    [Transaction(IsolationLevel.ReadCommitted)]
    public void Save(T entity)
    {
        mOrm.session.SaveOrUpdate(entity);
        mOrm.session.Flush();
    }
 
    #endregion
}

Much more simple. Example of using AttributeEnabledDAO is given bellow:

ProxyFactory articleDAOFactory = new ProxyFactory(
    new AttributeEnabledDAO<Article>());
 
articleDAOFactory.AddAdvisor(new DefaultPointcutAdvisor(
    new AttributeMatchMethodPointcut(typeof(TransactionAttribute)),
    new TransactionAroundAdvice()));
 
IDAO<Article> articleDao;
lock (synchObject)
{
    articleDao = (IDAO<Article>) articleDAOFactory.GetProxy();
}
 
Article article = articleDao.Load(1);
article.Name = "Paracetamol";
article.SalePrice = rnd.NextDouble();
articleDao.Save(article);

16 August 2006

ADO.NET vNext CTP is out

Microsoft has just released ADO.NET vNext CTP. This CTP includes the preview build of the long waiting ADO.NET Entity Framework. This Entity Framework is Microsoft's ORM tool. If you are wondering what is ORM tool take a look at my post about
NHibernate session management.
Presentation with features of Entity Data Model can be found here. If somehow Link* technologies looks messy for you, taka a look at this presentation.

06 August 2006

Querying Microsoft SQL Server trace files

Have you ever wanted to be able to query saved SQL Server profiler trace files (*.trc)? Yes! Then you need to use fn_trace_gettable.

05 August 2006

Interview with Anders Hejlsberg

Take a look at this interview with Anders Hejlsberg. It's not about a future technology. It's about himself. Watching this video you will find answers to questions like: Why Anders left Borland and joined Microsoft? What is the secret of his success? Anders talks for the time working on projects like: Turbo Pascal, Delphi, C#. Enjoy!

Mocking static methods

Yes, the title is correct. Mocking static methods in .NET is possible with TypeMock library. There is no need to redesign you classes just to test them. In fact there is no need to write additional code to your classes. This is possible because TypeMock uses profiler's API to handle execution of methods and creation of classes. For a list of features look here.
Using TypeMock is pretty easy. In my previous post about NHibernate session management I'm using a static method to create appropriate session manager (take a look at GenericDAO constructor). The test of the constructor may be something like:


[TestFixture]
public class GenericDAOTest
{
    [SetUp]
    public void InitTest()
    {
        MockManager.Init();
        //ormManagerMock = MockManager.Mock(typeof(PerRequestWebManager));
        ormManagerFactory = MockManager.Mock(typeof(OrmManagerFactory));
    }
 
    //private Mock ormManagerMock;
    private Mock ormManagerFactory;
    private GenericDAO<Article> articleDAO;
 
    [TearDown]
    public void FinalizeTest()
    {
        MockManager.ClearAll();
    }
 
    [Test]
    public void TestDAOConstructor()
    {
        ormManagerFactory.ExpectAndReturn("GetInstance",
            new PerRequestWebManager());
 
        articleDAO = new GenericDAO<Article>();
 
        MockManager.Verify();
    }
}
 

Although TypeMock is powerful and easy to use library, there are some disadvantages. For example in the free version, when the test is started for first time, a popup dialog appears and invites you to buy the product. Also not all of the .NET types can be mocked (for more information take a look at this thread).