One of the issues I faced recently was to build a dynamic site map path for given page. At first this seems like a piece of cake, the MSDN contains an article regarding the SiteMapResolve event which is perfectly suited for this task.
Alas, this would be too simple. Do you see why the MSDN example is completely broken and will not work at all?
Well, the answer is here:
You see, the SiteMapResolve is a static event which means that every time the page is loaded it will add yet another handler for this event! After few thousands of requests, few thousands instances of the same handler will be attached to the the event! And guess what? Since all handlers return a value and the event expects a single value, the value from the handler which was attached as the first one will always be returned.
A complete disaster!
There's one way to overcome this mess - you have to attach an event and then unattach it. This approach is described in the CodeProject's A Better SiteMapResolve article.
However, I think that this approach has two major disadvantages:
- your page has to inherit from specific BasePage class
- even though handlers are attached and then unattached, threading issues still can occur since it is possible that for a period of time more than one handler is attached to the event
How to solve this issue then once and for all?
Well, let's have a single event handler, attached once in the Application.Start event. Then, when the handler fires, we'll check whether current handler (page) implements our specific interface and if this is so, we'll redirect the execution to the handler.
Let's start with the definition of the interface:
Let's also modify the GlobalApplication class to add a single handler for the SiteMapResolve:
and then let's implement the interface on a specific page: