Thursday, 14 July 2011

Non expected exception on IPAddress.TryParse

Lately, for the one of our client we implemented a functionality which uses Geo Location as a basic visitor recognition. The problem appeared after the functionality had been promoted to the live environment - it simple did not work. After a quick investigation we founded that the problem is caused by Akamai which acts as a proxy for whole domain.

The solution itself is pretty simple. Akamai can be configured so that it sends additional Http Request Header with original IP. I just thought that some basic validation on this header value would be great, so I have added something like code below:
var headerIp = request.Headers["True-Client-IP"];
IPAddress akamaiIpAddress = IPAddress.None;
var isValidIp = IPAddress.TryParse(headerIp, out akamaiIpAddress);

As you can see I laveraged on IpAddress class to determine whether sent header is correct. The problem was that if there was no header I had had the exception on that line. Why? The answer is very simple, and very unexpected - you can not pass null as a first parameter. I changed this line slightly in the following manner:

var headerIp = request.Headers["True-Client-IP"] ?? string.Empty;

and problem disappeared. I always thought that TryParse method on any object should swallow any exception, because it is expected from it. This is one of the most deceiving thing I have met in .NET. Does anyone know if any other TryParse method potentially throws exceptions as well?

Monday, 23 May 2011

Integrate Sitecore.Logging with Castle Windsor


Abstract
A couple of months ago I started using Dependency Injection pattern in my projects more consciously and extensively. Initially it was not easy and comfortable, however I found it very profitable and useful. I picked Windsor as a Inversion of Control container. In the same time Sitecore had come along as a new Web CMS platform in Cognifide range. As a natural consequence those two got married in my projects.

The issue
The first problem I encountered was a logging issue. I'm using the Logging Facility so that I don't need reference to log4net library, using ILogger from Castle.Core.Logging namespace. Using this facility has a big advantage - Windsor resolves current logger context automatically for maintained classes, so that you don't have to worry about it. If you would like to obtain current logger directly from container you can resolve ILoggerFactory, which creates a logger instance for you. However, this is not a case here. The case was that while everything seemed to be fine, no logs appeared, moreover Windsor always returned a default logger.

After some investigation I finally found the reason - apparently Sitecore guys took whole log4net project as is, changed it according to their requirements (please note that there are some additional configuration features in Sitecore log4net logging configuration section) and finally embraced it as a Sitecore.Logging library. This causes that Windsor is unable to create any logger instance, because it uses full class name to resolve types (note that there is no log4net library anymore, you have Sitecore.Logging instead).

The solution is simple and pretty straightforward. First you should read great Michael Edward's post where he explains why logging doesn't work by default. However I would like to go one step ahead and keep my custom functionality "Sitecore free". Therefore I would like to keep using ILogger and by that be free from additional dependency like log4net or Sitecore.Logging. To achieve my goal I had to register my own facility just like in Michael's post, then I had to write my own custom ILoggerFactory and ILogger implementations. Both are very simple , for example ILoggerFactory has four methods and one of them is
public ILogger Create(string name)
{
return new SitecoreLogger(log4net.LogManager.GetLogger(name));
}
where SitecoreLogger is ILogger implementation. Please note that I pass internal logger in constructor so that I can leverage on it in my implementation. In fact, it is only a wrapper for native logger. ILogger has a number of various methods and each of them is similar to written below:
public void Error(string message, Exception exception)
{
InnerLogger.Error(message, exception);
}
To use it you have to add a custom facility, the simplest way is doing that from code, where you simply indicate that logger should be created by a custom factory:
container.AddFacility(p => p.LogUsing<SitecoreLoggerfactory>().WithAppConfig());
where container is a IWindsorContainer instance, and log4net configuration is in web.config file. You can register it like Michael proposed in his post from configuration file as well.
Conclusion
Solution above allows me to use logging in a loosely coupled way, and keep my custom functionalities as intended - clean and free from unnecessary dependencies. This code is fully open source so feel free to download and use it or adjust it in your project.

Refrences




Monday, 15 March 2010

Mental spring's cleaning

Today, I'm not going to introduce anything technical tips or features. I'd like to write a few sentences about (not)using design patterns and good practises.
I'd like to review my habits, developers' habits, but only mine?

Recently, I have read two fantastic blog's entries:
1. Ayende Rahien's Nice process but what about the engineering bits
2. Udi Dahan's On small application
and I have started to have more deeper thoughts (which I'm always trying to avoid - the headache is terrible after that ;-)) about my profession and projects I have participated.

It's never a good time to make negative comments and give an instructive notes, but sometimes its a necessity to say a few bitter words and have moment of reflection.

In various discussions I am constantly hearing and reading who is more agile, how to improve the process, how to make each of iteration/sprint in process more efficient and how to meet tight deadlines... but, are those discussions should be the most important ones for developer? Why there is so many opinions and debates about the process if we don't have influence on time-frame and requirements? In my opinion, discussions are not going in the right direction for majority of us. Each of the process:Agile, Kanban, XP, RUP; is good enough to design and create high-quality software as long as developers don't have to bother about it, just using him properly.
Maybe I don't get it, but I worked with two of them which are drastically different, but still the main quallity difference between them was made by people - their knowledge, commitment, teamwork and attitude bring much more than MS Project diagram or white cards well-organised on the whiteboard.

Instead of it there are some things that seems to be lost and forgotten these days. In my opinion more important and worth to be discussed. Things that makes my profession so inspiring and which can seriously damage my family life. Designs patters and best practises... sounds familiar?
So why I feel that we aren't remember the simple principles of object oriented art?
Why we aren't improving and refactoring our code which is our only real value we can really rely on?
Please ask yourself when did you use some of design patterns last time (please leave the Singleton in peace, because in that case the issue is rather in the second side)?
Please ask yourself when did you consider the single resposibility principle during developing some new functionality?
When did you consider the loose coupling principle when you had adding some dependency lately?
Please ask yourself when did you learn some new features last time?
Which new fancy library have you tried?
When have you tried to do your tasks better/different that usual?

My consience doesn't look too good. Most of answers above sounds 'no' for me. I can say more here - it is a pretty normal that we feel a bit unconfortable with the code we wrote sometime, two or three years ago. But I, in fact, I found some code I am shamed of which is no older than two or three months... I have to use svn's blame because I couldn't believe that I wrote it... very sad but true... I have this terrible headache again now...

The winter is ending and the sun is faintly shaning from behind the clouds makes days better and better. I think there is a perfect moment to change things are they used to be. So I have decided to start from my own yard and make a big spring cleaning in my mental working environment and promise myself a few important things:

1. No more comfortable and quick, but simply bad designed and dubious quality solutions. Even if I am faced with a simple thing, even if its only once, even if its only for now.
2. No more code without any comments, both a documentation style ones and a hint style ones.
3. I will start to use unit tests as a one of my common way to develop things, maybe not as much as I should, but like it used to say ex-coach of our national football's team Leo B. "Step by Step", one by one to make a progress in this area.
4. I will spend some percent of my working hours actually refactoring the code and update the assumed flow and model, because what let us be more professional and mature than when our visions become materialized as predicted and designed?
5. I begin to do the task of considering how to do it rather than when I do it.

I hope that I will look at this list this fall and I will be a proud that in two or three points I made a progress...