Living .NET...

Musings on .NET, and the like - Manoj G [MVP, Connected Systems Developer]
Using Interception with Dependency Injection: EL 4.1 and Unity Spring 1.2 create new avenues

It is customary to conceive any large application to be composed of several logical layers. It is also a practice to reduce the coupling between the layers. Typically, one would create an interface  for each class of each layer and they would be coupled to the downstream layer classes only though interfaces.

  
You would also typically want to unit test each class in each layer. By definition, each of unit test would test a method of only one class and not the downstream classes it depends on. To achieve this , one would need to mock out the instances of the classes which the class being unit-tested depends on.  To bring all of this to play effectively, you need  to implement the Dependency Injection pattern in your application. Dependency injection is provided by Unity application block.

The application we talked about earlier has in addition to a lot of business logic, several pieces of cross cutting logic - logic applicable to all classes - like logging, tracing, authorization, validation etc. The code for these concerns are usually generic. It would be an awful amount of work to implement these generic pieces of code in every class  (or a group of classes) of your application. What you really need is some way to stitch these concerns into the application without disturbing the application code too much. This style of programming is called Aspect Oriented programming (sort of).  This capability is provided by the Policy Injection Application block.

Now, to me, both aspects  discussed above are very important to any application. In other words, any application would need both dependency injection along with some type of aspect orientation (or policy injection or interception).  The question really is - how do you really bring them together?

I am assuming that you are familiar with these blocks I just mentioned. To have rubber meet the road, we really need to marry IContainer.Resolve<T> and  PolicyInjection.Create<T>(). This was not possible  as of EL 4.0 and left me hoping. It is possible now - with EL 4.1 (along Unity 1.2). The interception capability comes as a extension which can be associated with the Unity container. Therefore, you can have policies associated with the container which govern which call handlers are added. The real beauty is this - the application classes really work with the IContainer interface. In an actual environment, you need to associate the container which has the correct dependencies and interception policies. The unit testing environment would basically replace the container with one where the Interception extension is not applied, and therefore, the unit tests would not really execute any cross-cutting logic (of course, you can choose otherwise). Neat!

I have just started to dabble with this ability, and a lot of questions still need to be answered. One that comes immediately from the top of my mind is performance. When a class is set to be intercepted, what would be the performance overhead, and what would be the overhead based on the type of interceptor (TransparentProxyInterceptor, VirtualMethodInterceptor or InterfaceInterceptor)? Obviously, there are no definitive answers and it all depends on the policies and handlers you add to your application. I have a reason to believe that the cost of interception is not usually so high, that is deemed only for academic purposes. One would need to perform relevant tests to ratify the same in her application on the representative environment. The second question, but seemingly more subtle, is instancing. The new interception features either work on the RealProxy based interception, or dynamic code generation.  Obviously, it would be more efficient to reuse these instances at runtime instead of generating them for every call. Now, if you have singleton instancing, the real question is about thread safety. How does a dynamically generated instance serve multiple request threads at a time - as it happens in web applications in production?

Having opened these questions, I would write up a follow-up post which hopefully addresses these. In the meantime, I will dabble with more scenarios using these new capabilities, and keep you posted.

Posted: Fri, Jan 16 2009 14:50 by Manoj G | with no comments
Filed under: ,
Best practices in Workflow Design - Part 2

Naming convention in Workflows

Workflow activities should be named appropriately. As much as possible, they should reflect names form the business domain. For example, it wouldn’t appear good to have names like ifelseActivity1 or callExternalMethodActivity1. Instead, it is good to have names like ifProductsExists and MakePayment respectively. Shown below is a good example of the same:

Good Naming conventions

Custom activity names should really represent their purpose. Good examples are ApproveRequestActivity. It is customary to suffix custom activity classes with “Activity”. It is also a good practice to provide apt descriptions to all the activities in the workflow. This would help better understand the nuances of the workflow logic.

Transactions in Workflows

In application design, avoid scenarios in which transactions need to span between business components and workflow logic. Either a database transaction should complete before the workflow is invoked, or should be started and completed within the execution of the workflow sequence (using a TransactionScope activity, for example). In either case, care must be taken to ensure that the transaction (and hence, locks on shared resources) should not be kept alive for a long period, as this adversely impacts performance. For long running transactions, compensation should be employed for undoing the effects of a prior transaction. WF has adequate measures (compensatable activities) to incorporate the same.

Sequential versus State machine workflow

It is definitely possible to represent a workflow scenario of a business application as a sequential or a state machine workflow. State machine workflows appear to be the right logical choice for long running business operations, which can typically be visualized as those transitioning from one state to another by means of some human or process input. A sequential workflow may be harder to represent the entire workflow process in these cases, thought it is not impossible. 

State machine workflows also provide for better tracking of the process. Since each state in a state-machine workflow represents a logical step in a business process, the give better visibility into the current state of the process. Refer to this blog post for more info on the usefulness of state machine workflows.
Note that states within a state machine could have sequence of activities. Sequential workflows have their own place and have to be used appropriately.

Workflow Instance Identifiers - Correlation

Workflow scenarios, typically state machine ones, involve persistence. Here, the workflow waits for an event to occur and hence its state is persisted into the database. The workflow is brought to life by another part of the application which loads the hydrated instance and executes the workflow (perhaps transitions it to the next state). The unloading and loading is correlated by the WorflowInstanceId (a Guid value). It is the application’s responsibility to keep this value and then use it at a later point of time. It could be a wise thing to store this value in the database alongside with the other information and then fetch the same for correlation at a later point of time.

It is perhaps, not a good practice to wait for the runtime to start the workflow so as to get the WorkflowInstanceId. A better approach is to generate the Guid value and pass it the workflow runtime as a parameter. This helps in situations where starting a workflow is a small part of a transactional business operation, and you need to keep the WF runtime pieces out of transaction scope.

Error Handling in Workflows

It is important to understand that error handling in workflows is as important as those in the business components.  Workflows that encounter an error, either through an exception thrown by a called service or that is raised internally, go in faulted state and complete prematurely. Since the execution nature of workflow is asynchronous, unhandled exceptions are not raised to the application and go unnoticed. This could adversely affect several parts of the application expecting a persisted workflow, especially in the case of a state machine workflow. Since the faulted workflow goes to the closed state, the application expecting the workflow to be in a specific state is left in an unrecoverable situation.

To avoid such situations, one should include appropriate fault handlers in the workflow.  An example of the same is shown in the figure below. It would be the responsibility of the fault handler to take the workflow to a recoverable state. The fault handler could do things like logging the exception details, persist recovery information and so on, analogous to a catch block in C#.

Error handling in State Machine Workflows

State machine workflows are to be handled in a different way. State machine workflows do not have a workflow-wide fault handler collection (it does not make sense either). Here, one should provide a fault handler for every sub-activity within each state activity. It is a good practice to keep the semantics of a state machine even in the event of a fault. This can be done by having the fault handler move the workflow to a user-defined error state. At this state, the workflow could either wait for recovery to happen, might just log and exception and move to completed state, or whatever is the apt handling logic for the application. You could consider options for retrying for a fixed number of times as well.
 
Workflow Cancellation

Cancellation of workflows is handled similar to Faults. One should wire appropriate Cancellation handlers to every activity. Like a fault handler, the cancel handler should gracefully close a workflow by taking the appropriate action.
 

Posted: Tue, Jul 15 2008 4:36 by Manoj G | with no comments
Filed under: ,
Best practices in Workflow Design - Part 1

It’s been a awfully long time since I have published a blog entry, and it seems like the world of technology has changed quite a bit since! The hiatus is over now, and I would like to starting putting down some thoughts and experiences on my new interest – Connected Systems. WF and WCF are the pretty much the atoms for building connected systems on the .NET platform, and a large percentage of my upcoming posts would be focused on these technologies.

In this post, I want to talk about some aspects of workflow design based on my experience, which I think can be classified as idioms or best practices.

Workflows should contain only ‘flow of logic’ and not the logic itself

It is easy to visualize workflows as business logic which is modeled using a designer. It is common to see developers transform their typical business logic into workflows by separating different parts of the logic into separate workflow activities. Here, we see lots of procedural code gets transformed into workflow models. This is clearly not the right thing to do. Workflows are not be be plain replacement for existing business logic components. Workflows are to be used in specific scenarios - like long running business processes, rule driven logic, dynamic flow changes etc (I'll cover this in a later post as well).

The figure shown below contains a snippet of a bad workflow design where procedural logic is transformed to a workflow through usage of code activities (in an order processing application):

Bad Workflow Design

Avoid business logic code within workflows

Ideally, workflows should not contain busines code themselves. In other words, as much as possible, usage of CodeActivity should be avoided (at least, it should not contain business logic). One way to take out business logic contained in code activities is to replace them with CallExternalMethod activity, where you invoke upon a method of a registered service. A better way would be to create a custom activity, where we override the Execute method, and within it delegate the business operation to a registered service. This way, taking individual pieces of business logic out of the workflow also helps us to unit test them in isolation. If a workflow is designed well, it would not have any code in its code-behind logic. This approach would also help us in scenarios where we have only XAML-based activation of workflows.

Given below is a snippet of a custom activity which is used in the Purchase Order creation workflow, and updates the status of a workflow in the database. The Execute method contains the usage of a registered service to which the business operation is delegated to (updating of the status field in this case).

public partial class UpdateOrderStatusActivity: Activity

{

        private static DependencyProperty PurchaseOrderProperty = DependencyProperty.Register("PurchaseOrder", typeof(PurchaseOrder), typeof(UpdateOrderStatusActivity));

 

        public PurchaseOrder PurchaseOrder

        {

            get { return (PurchaseOrder)base.GetValue(PurchaseOrderProperty); }

            set { base.SetValue(PurchaseOrderProperty, value); }

        }

 

       

private static DependencyProperty OrderStatusProperty = DependencyProperty.Register("OrderStatus", typeof(string), typeof(UpdateOrderStatusActivity));

 

        public string OrderStatus

        {

            get { return (string)base.GetValue(OrderStatusProperty); }

            set { base.SetValue(OrderStatusProperty, value); }

        }

 

          public UpdateOrderStatusActivity()

          {

                 InitializeComponent();

          }

       

 

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            IOrderProcessWFService orderService = executionContext.GetService<IOrderProcessWFService>();

            orderService.UpdateOrderStatus(PurchaseOrder,OrderStatus);

            return ActivityExecutionStatus.Closed;

        }

   }

 

I'll try to cover more best practices in my next post. If you have better suggestions or comments, please do share it!

 

Posted: Sat, Jul 12 2008 6:00 by Manoj G | with no comments
Filed under: ,
WCF - A Perspective

.NET 3.0 has been made available to all the developers recently. With it comes a set of new set of API, which are simply there to unleash the .NET developer’s potential to create the next wave of powerful applications. These API, formerly called WinFX, take the form of four pillars – WCF, WF, WPF and WCS. In this post of mine, I would like to give a perspective on the Windows Communication Foundation (WCF). 

Most typically, one starts off an introduction to WCF by explaining the four tenets of SOA, and how WCF embraces them from the ground-up. While this is very reasonable, I would like to think about WCF from a slightly different perspective which, of course, would eventually flow into confluence of the SOA tenets. To get a great insight into these tenets, I would urge you to look into this paper by the venerable Don Box.

WCF, in a nutshell, is all about facilitating message exchanges between endpoints. Note that ‘message’ and ‘endpoint’ are underlined. Well, these are but, what WCF is all about. These are concepts through which SOA is realized. Let me give you my understanding on these concepts:

If any entity needs to communicate with the world, it does so with Endpoints. Endpoint comprises of three elements (commonly called as ABC):
Address (Where)  - Where can I find the service, the URI?
Binding (How) - How can I communicate with the service? What are security requirements, encoding requirements etc.?
Contract (What) – What is the structure of the messages that I need to communicate with the endpoint?  What are the message exchange patterns (like Request/Reply, OneWay etc)

A WCF service would therefore, have at least one endpoint; it could have multiple based on different combinations of bindings, contracts or endpoint addresses.

If you really look at it, the concepts embodied by WCF aren’t new. They were pretty much present in ASMX. What lacked was that these concepts/abstractions were not explicitly codified in the ASMX (ASP.NET) framework.  ASMX just seemed to be a quick way to get .NET classes to talk SOAP. So, caught in a world of classes and attributes, developers lost sight of underlying concepts that manifested as wsdl:portType, wsdl:port, wsdl:message and wsdl:binding.

WCF, on the other hand makes these concepts explicit, as seen in the ServiceEndPoint, BindingContractDescription, and EndPointAddress classes in the System.ServiceModel namespace. It is this object model that makes WCF very powerful. The number of out-of-the-box bindings available, and the existence of several extensibility points speak of the raw power of the WCF programming model. Also, this architecture is what makes unification of several programming models like MSMQ, COM+, WSE etc. possible.

“Message”, which can simply be thought of as the data/document/information exchanged between endpoints, is a first class citizen in the WCF programming model. Unlike its predecessor, where messages meant no more than an XML document (or stream) representing the SOAP envelope, WCF provides much better representation and finer control over messages. Messages are represented by the Message abstract class in the System.ServiceModel.Channels namespace.

Having seen how endpoints and messages are dealt with in WCF, it can be safely asserted that we are now consciously moving from the procedure call paradigm to a message exchange paradigm.

To find out more about WCF architecture, and the core classes that make up WCF, refer to this excellent paper by Yasser Shohoud.

Update:

As a part of the community launch of Windows Vista and Office 2007 in the B.NET User Group, we, a group of MVPs and other active community members authored a small e-book, comprising of articles on Vista, .NET 3.0 and Office 2007. Based on this post of mine, I wrote an article on what I thought the underpinnings concepts of WCF were. You could download the PDF of the e-book here.

 


Posted: Sun, Jan 14 2007 16:24 by Manoj G | with no comments
Filed under:
Implementing Timeout & Retry

I have come across several situations where I need some sort of Timeout functionality for a particular operation. At the same time, I also needed a provision for retrying the operation a few times before calling quits. I thought about a solution using ManualResetEvent and a Timer which I have outlined below:

const int MAX_RETRIES = 5;
const int RETRY_INTERVAL = 10;    //10 seconds
const int OPERATION_TIMEOUT = 1; //1 minute

static void DoOperation()
{
    
int retries = 0;
    
int timeout = 0;

    ManualResetEvent waitHandle = 
new ManualResetEvent(false);

    
//Use a timer to retry the opeation periodically
    
Timer retryTimer = null;
    retryTimer = 
new Timer(
           
new TimerCallback(
               
//The operation to carry out is represented by this anonymous method.
               
delegate(object state)
               {
                   
try
                   
{
                       
if (retries > 0)
                       {
                           
//The operation has failed before. So you may want to handle 
                           // that situation here.
                           
Console.WriteLine("Retry attempt: {0}", retries);
                       }

                       
//Do the operation which may fail or timeout. 
                       
Console.WriteLine("Doing some major operation now.");

                       
//throw new Exception("Some exception");
                       //Thread.Sleep(1000);

                       //Checking whether the operation timed out. In this case, the
                       // thread isnt forcefully aborted, so you can exit gracefully
                       //Else, you may need to handle the ThreadAbortException
                       
if (timeout == ManualResetEvent.WaitTimeout)
                       {
                           Console.WriteLine("It seems that the operation timed out. Need to exit gracefully");
                       }
                       
else
                       
{
                           Console.WriteLine("Operation completed");
                       }

                       
//Set the waithandle if the opeation is successful
                       
waitHandle.Set();

                       
//Everything went well. Close the timer.
                       
retryTimer.Dispose();
                   }
                   
catch (Exception e)
                   {
                       
// Handle the exception

                       
retries++;

                       
//Check if the number of retries has exceeded the maximum allowed
                       
if (retries > MAX_RETRIES)
                       {
                           
//Do some logic to handle this situation
                           
Console.WriteLine("Operation has exceeded maximum attempts");

                           
// Set the waitHandle so that the method returns
                           
waitHandle.Set();
                       }
                       
else
                       
{
                           
//Retry the operation or any do alternative logic here
                           
Console.WriteLine("The operation failed and will be retried in a short while.");
                       }
                   }
               }),
           
null,
           
new TimeSpan(0, 0, 0),
           
new TimeSpan(0, 0, RETRY_INTERVAL)); // The timer retries the operation for the specified interval

    //Wait for the operation to complete or timeout.
    
timeout = ManualResetEvent.WaitAny(
       
new WaitHandle[] { waitHandle },
       (
int)new TimeSpan(0, OPERATION_TIMEOUT, 0).TotalMilliseconds,
       
false);

    
if (timeout == ManualResetEvent.WaitTimeout)
    {
        
// The operation timed out. Abort the operation thread or exit gracefully.
        
Console.WriteLine("The operation timed out.");
    }

    waitHandle.Close();
    retryTimer.Dispose();
}

Let me explain this code section which may look a little convoluted at first. One of the easiest ways of implementing the timeout functionality is using WaitHandles. In the sample above, I have used a ManualResetEvent, but I guess you may use other WaitHandles like AutoResetEvent** etc, as you see fit. The idea is to spawn off a thread to execute an operation (which could possibly be a long one), and then wait for the thread to signal completion through the ManualResetEvent’s Set method. The ManualResetEvent provides a static method called WaitAny which can be used to wait for a specified period of time on one or many waithandles (In our case, it is just one). 

Retry logic can be implemented using a Timer (System.Threading). The Timer event is where the meat of the work is done. The exception handler basically does the work of checking if further retries are required by checking a counter. Once, the process successfully completes, the WaitHandle is Set and the main thread is signaled.  

**At first, it may be difficult to differentiate  or choose between ManualResetEvent and AutoResetEvent. AutoResetEvent is analogous to the doorbell switch, which goes back to the off state once you press and release it. AutoResetEvent resets itself automatically once you set it. ManualResetEvent, on the other hand, does not reset automatically - it is like a normal switch. Therefore, ManualResetEvent can be used when signaling happens once and for all, and subsequently, threads need not wait again for another signal. AutoResetEvent , on the other hand, can be used for finer coordination between threads, when signaling can happen intermittently.

*Disclaimer:
I don’t suppose this is the best way to achieve timeout and retry – this is just one way. Do let me know if there are better techniques!

Posted: Wed, Nov 1 2006 17:58 by Manoj G | with no comments
Filed under:
Predicates in Action

Generics offer tremendous flexibility – in more ways than you would ever know. Predicates are a good example for this. .NET 2.0 BCL comes with certain generic delegates – Action<T>, Predicate<T>, and Converter<Tin, Tout> respectively. Their definitions are given below:

public delegate TOutput Converter<TInput, TOutput>(TInput input);

public delegate void Action<T>(T obj);

public delegate bool Predicate<T>(T obj);

If you look at the definitions, you can guess that the instances of these delegates hold references to methods that do type specific operations. For example, the Predicate delegate represents a method which takes an instance as parameter, and determines if the instance meets a particular criteria. Quite obviously, these delegates would be most applicable to generic collections and arrays. The List<T> class for instance, employs them  in Find, FindAll, Exists, FindIndex, FindLastIndex, ForEach methods. You could find similar usages in the Array class.

The real cool thing is using predicates in concert with anonymous methods. At first, it may look convoluted, but actually, that makes coding real easy (and fun). The oversimplified code snippet given below does a couple of things – given a list of accounts, it finds all accounts with a zero balance, and for each of these accounts sends a mail notifying the same. The FindAll method uses a Predicate<T> delegate and the ForEach delegate employs the Action<T> delegate.

List<Account> accounts = GetAllAccounts();
accounts.FindAll(
        
// Uses the Predicate<T> delegate
        
delegate(Account account)
        {
            
return (account.Balance == 0);
        }
    ).ForEach
    (
        
//Uses the Action<T> delegate
        
delegate(Account account)
        {
            SendMail(account, "Be aware, you now have a zero balance");
        }
    );

What you may have noticed is that we have completed avoided nested for/foreach loops here. I have used anonymous methods inline here, but you can easily replace them with delegate instances so as to accommodate different criteria or action items at runtime. In more advanced cases, you could generate predicates at runtime based on user provided business rules or something like that.

Thus is the amount of flexibility could can reap out of generics! I would strongly recommend one to go over this interesting MSDN Magazine article on Predicates by Ken Getz to get a better idea.

Posted: Tue, Aug 29 2006 13:12 by Manoj G | with 3 comment(s)
Filed under:
Musings on Web 2.0 - Part 2

In my previous post on Web 2.0, I mentioned that one of the new trends in the web today is that of “mashups”. The idea is about getting data from multiple, disparate sources and collating them in interesting ways. For example, let’s say we need to create a mashup involving a map showing all theatres playing the highest rated (most popular) movie in a particular city. Now, to develop this, one would need several pieces of data from several sources. First of all, you need to use map services (like Google Earth or Virtual Earth) to show a map. Secondly, you need a service that lists all popular theatres in a particular city, and what they are currently showing. You would also need ratings and reviews for all the movies that are being screened. Today, all these pieces of information are currently available, but mostly in several different websites. Each of these web sites could have their own revenue model revolving around special services they provide (maybe reviews, for example). So, our mashup which we conceived earlier would receive a setback if there is no data/service available which provides that information in an easily consumable form. In other words, you need structured data to make magic happen.

HTML traditionally, has not been considered as structured data. Perhaps, that is why we have XML to represent complex data forms. But how do you represent information in XML for the web? One answer would be SOAP and Web Services. As revolutionary as web services are for business applications, I feel they are not that conducive to AJAX-based Web 2.0 applications of today. The reason is that SOAP isn’t simple anymore; or at least, for naïve JavaScript-based clients. The evolution of WS-* has morphed SOAP into a monstrous stack of composable standards, which is beyond the reach of simple scripting today.
 
So, the order of the day is XML, but in simpler formats, and which are accessible through simpler protocols. Perhaps, this is the reason why RSS and ATOM were born, and are very popular today. Perhaps, this is the reason why REST is gaining momentum. Today, we see a large ecosystem of applications built around RSS and REST, and this can be attributed to their simplicity.

While XML is really powerful, the inherent concern of web applications to incorporate XML to express semantics could seem to be additional investment in time and space. If we go a step backwards towards HTML, and look for ways of expressing semantics, we wouldn’t have an answer, right? Wrong. Apparently, HTML has certain attributes like rel, class, and rev that are rich enough to express, and at the same time could be decoupled from visual markup. This is the idea underpinning a new way of semantic expression on the web – Microformats. Microformats, like RSS, are creating a whole new ecosystem of standards and applications (like crawlers and bots) that make structured data even more pervasive and accessible.

Microformats are a Web 2.0 phenomenon, and are testimonial to what I had to say earlier – Web 2.0 has brought about new "innovative techniques" of harnessing existing technology stacks. Be it through XML or Microformats, hopefully, the World Wide Web will evolve into one large blob of structured data available for everyone to create mashups like never before!

Posted: Mon, Jul 24 2006 2:41 by Manoj G | with no comments
Filed under:
Musings on Web 2.0

Web 2.0 – undoubtedly, is one of the most debated software buzzwords in the recent times. [The other term, in my opinion, which has attracted a lot of debate (and abuse) in the recent history is SOA]. To many, it is just about embracing new techniques, which are DHTML and JavaScript centric. But excavating the early manuscripts of Web 2.0 (like Tim O’Reilly's canonical Web 2.0 article) reveals a bigger picture. 

So, what exactly is Web 2.0? Here’s another very brief perspective to add to thousand others already existing in different flavors. I would start by putting it this way (the world’s smallest definition of Web 2.0): A set of new ideologies combined with a set of novel techniques for building today’s web applications. Another definition could simply be – a new ecosystem of applications (or say “services”) built on the WWW platform.

The new ideologies:

1) The Web Platform

Websites today are not just places where static information is presented, or which offer a single service (like e-mail, storage, forums etc). Websites today are platforms in their own right. They offer the capability to “compose” disparate applications to build a very powerful whole. The word “Mash-Up” is a popular term used to represent this ideology of mixing (or re-mixing) data and functionality. Now, part of this realization is capable by seeing our large world of applications as services, which can be consumed in non-proprietary ways. Not just SOAP, but plain old JavaScript itself is turning out to be that duct-tape technology making this possible. Live, Google and PageFlakes are great examples of the same.

2) De-centralization of the Authority & Data

Websites of the past era basically owned the content and its presentation entirely. With Web 2.0, the authority on the source of the data and its presentation shifts to the user. The website or web application basically provides a canvas which the user leverages to consume (and compose) services from disparate sources to meet their needs. As an example, you could cite msn.com (of the yester years) giving way to Live.com of today.

3) Collaboration

This is new trend to surface in recent past. Websites today are opening the doors to the world to participate, contribute and collaborate. In this model, users directly contribute to the data/knowledge base of the website. The exemplar of this ideology is “Wiki”s, and Wikipedia, which is one of the most popular websites today. Tim O’Reilly’s article rightly calls this “Harnessing Collective Intelligence”.

The Novel Techniques:

HTTP, DHTML, JavaScript haven’t changed much in the recent times. But these days, you get to here a lot of new jargons popping all over the place, all of these based of these fundamental technologies. At the lead of this jargon parade is AJAX (Asynchronous JavaScript and XML). Some others in this list are Comet, JSON, etc. An extensive examination of these would reveal that these are nothing but simple tweaks and hacks to existing methodologies like XMLHTTP and JavaScript’s own eval function. Therefore, I term these seemingly “new technologies” as novel techniques. 

New or otherwise, these techniques and ideologies definitely have resulted in new possibilities and opportunities for web application developers. We are seeing new revenue models which transcend the notion of simple buying and selling which we saw in the recent past. A new journey has just begun, it is time for us to get on the bus and be a part a long adventure!

 

Posted: Mon, May 29 2006 1:42 by Manoj G | with no comments
Filed under:
Tip: Debugging Windows Services

The other day, I was watching the PDC presentations on WCF and one of them was on hosting WCF services by Steve Maine. Part of the presentation was about hosting Indigo on Windows services (or NT Services). One of the demos had a small and very interesting tip on debugging service startup, which I shall try to elaborate here.

I always wondered how the service startup code could be debugged. There are two problems which you would face invariably. First of all, there is no process to which you can attach a debugger to start with. I have done stupid things in the past to step into startup code - by adding a Thread.Sleep in the OnStart method, assuming that this would give me enough time to attach the debugger to the newly started process. This isn’t very smart as you would hit the second problem – the Service Controller Manager (SCM) would time the service out way too soon. Not to worry much - there is any elegant solution to both these problems.

You need not add a Thread.Sleep anymore – just add a Debugger.Break in your code. This isn’t new, but I simply hadn’t found a use for this before. This method is actually pretty useful if you want to conditionally attach the debugger in situations like this.

The solution to the problem of the SCM timing out is a method in the ServiceBase class (System.ServiceProcess) that has been added in .NET 2.0. This method is the RequestAdditionalTime, which takes a single parameter – the amount of time in milliseconds that the SCM has to wait additionally before pulling the plug on the service. Note that this method can only be called inside of OnStart, OnPause, OnContinue and OnStop (basically all the commands you can forward to the SCM).

Neat!

Posted: Tue, Apr 4 2006 0:25 by Manoj G | with no comments
Filed under:
Useful additions in .NET 2.0 - Part 3: EventHandler<TEventArgs>

If your .NET class needs to generate events, at a minimum, you typically do the following:

1) Create a new class which derived from EventArgs – the instance of this class would be used to communicate certain information to the event handler about the event itself. For example, CacheExpiryEventArgs. 

2) A new delegate type whose instance points to a method, the signature of which looks something like:

      public delegate void CacheExpiryEventHandler(object sender, CacheExpiryEventArgs e);

 3) You declare an event which is associated with the delegate you created in (2). For example,

      public event CacheExpiryEventHandler CacheExpired

Now, for every event in your application, you invariably create as many delegate types. If you notice, each of those delegates differs only by the second argument of the event handler – the class representing the event arguments. Now, wouldn’t it be great if you had a generic delegate parameterized by the respective EventArgs argument. With generics in .NET 2.0, this is exactly what you get, in the form of EventHandler<TEventArgs>. With this in place, our example now would look like:

     public event EventHandler<CacheExpiryEventArgs> CacheExpired;

This is definitely convenient, as it would reduce the number of delegates that are created in any application. Generics is a great addition in .NET 2.0, which not only gives you performance and strong-typing, but also certain productivity benefits like in this case, and for that matter Nullable<T>, List<T> and may such instances.

Posted: Mon, Jan 2 2006 0:28 by Manoj G | with 1 comment(s) |
Filed under:
Useful additions to .NET 2.0 - Part 2: Nullable Types
Nullable types, put in simple terms can be thought of as a way of having nullable value types. Quite obviously, one of the largest applicability of this concept is that of database programming, where you can associate a null value with any datatype. Not too long ago, while coding the data access layer, I did quite a lot of magic value checks on values to see whether I had to associate a null value (DBNull.Value) to the corresponding database parameter. This included Guid.Empty, Int32.MinValue, DateTime.MinValue and so on. So, I had to create one helper method for all the types that needed such checks. The example for int is shown below:
 
static object GetDbIntValue(int val)
{
    
if (val == int.MinValue)
    {
        
return DBNull.Value;
    }
    
else
    
{
        
return val;
    }
}
 
Now, this effort is not good in a lot of ways though it serves its purpose. This methodology would require a handshake between the Business Logic Layer (BLL) and the Data Access Layer (DAL) as to what values are acceptable and what are not. The problem is that there is no universally accepted set for the same, and hence there would be semantic coupling between the Biz and the DAL layers. The handsome alternative to this situation would be to use Nullable types. Wherever you used magic values, replace them with the corresponding instances of Nullable<T>. Most typically, these would be in the data transfer objects (DTO). In the DAL, we could now have a single helper function (in lieu of many in the earlier case), which looks something like:
 
static object GetDbValue<T>(Nullable<T> val) where T : struct 
{
    
if (val.HasValue)
    {
        
return val.Value;
    }
    
else 
    
{
        
return DBNull.Value;
    }
}
 
An adroit developer might question whether this helper nethod is really required. Why not have the IDbDataParameter instances 'infer' the right Dbtype from correponding nullable types. For example, you might have wanted this snippet to work without a hitch:
 
Guid? id = Guid.NewGuid(); //Just an example 
SqlCommand cmd = new SqlCommand("Select * from Sample where id = @Id");
cmd.Parameters.AddWithValue("@Id", id);

But unfortunately, at this point of time, there is no conversions built in for nullable types and you would end up getting this exception message:

No mapping exists from object type System.Nullable`1[[System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] to a known managed provider native type.
 
So, till there is support for Nullable types from System.Data (not sure why it should not be), you are better off using the simple helper listed earlier.
 
Before closing off, I would recommend that you read this article to understand all aspects of Nullable types. 
 
Nullable types, unfortunately, is fully supported only in C# 2.0, and not in VB. In other words, VB does not have the additional language additions and compiler changes needed to support nullable types in a way C# does. However, nothing stops you from using Nullable<T> in VB; it is just that you would not have the shortcut notations like in C# (int? etc). You are encouraged to read this blog post by Paul Vick, who explains this in detail.
Posted: Sun, Nov 20 2005 12:14 by Manoj G | with no comments
Filed under:
BackgroundWorker and SynchronizationContext

I have mentioned umpteen number of times earlier - .NET 2.0 comes with a wealth of new classes that have been added to the BCL. Today’s turn is of BackgroundWorker. If you look at the available documentation (circa Beta 2), this is what you will find:

“Executes an operation on a separate thread”. You first reaction would be “Heck, what’s so “new” about that?” Okay, so let’s spelunk into its properties and methods and try to find out.

 

Methods

RunWorkerAsync

Starts the designated method on a separate threadpool thread.

CancelAsync

Requests the cancellation of the pending background operation

Events

ProgressedChanged

This is called when the ReportProgress method is called

RunWorkerCompleted

Occurs when the background operation is completed

DoWork

Occurs when the RunAsync method is called.

 

Again, after looking at these, you thoughts wouldn’t change – “Still, what’s so great about the same? I had created similar helpers in .NET 1.1.”. Fine, let me tell what’s new. The very interesting aspect about the BackgroundWorker is the fact that RunWorkerCompleted and ProgressChanged event handlers would execute on the thread that created the BackgroundWorker object – most typically on a Windows form main thread (the thread on which the UI controls are created). Therefore, you now do not fall into a trap that you used to fall into earlier – updating a winform control on the wrong thread and facing unpredictable results. (Note that the DoWork method runs on a separate threadpool thread – do not update UI controls on that method)

 

So, you would now say: “Cool, the BackgroundWorker probably has a reference to the ISynchronizeInvoke object, and it would call Invoke on it to dispatch the method on the right thread. (System.Windows.Forms.Contrtol class implements the ISynchronizeInvoke interface) ”.

If you look closely, the BackgroundWorker is actually agnostic of the environment it runs in. It could not even be a winform application, or even if it was, it does not really rely on ISynchronizeInvoke directly. So, how does this magic happen?

 

With the help of the valuable services of Reflector, I came to know about a new class (a set of them actually) introduced in .NET 2.0, which

are responsible for this magic – SynchronizationContext. Here’s what the documentation says:

 

Provides the basic functionality for propagating a synchronization context in various synchronization models.  The purpose of the synchronization model implemented by this class is to allow the internal asynchronous/synchronization operations of the common language runtime (CLR) to behave properly with different synchronization models. This model also simplifies some of the requirements that managed applications have had to follow in order to work correctly under different synchronization environments

 

Can’t gather much from this explanation isn’t it? What is does mean perhaps is no more Control.Invoke. But it appears as if it is analogous to the thread’s Context object we had earlier, and a bit more specialized. By now, it would have rung another bell with you. As of .NET 2.0, in the case of Thread.Start method, the security context of the creating thread would be passed to the newly created thread. Guess what is behind this?

 

I tried a hand at this new class, simple stuff actually. I created a thread from the button click handler on a winform app and updated a control from the thread method (through anymymous method in this case). This is the snippet I tried:

 

private void button1_Click(object sender, EventArgs e)
{
    ctx = SynchronizationContext.Current;
    
// thanks to anonymous methods, everything here is inline
    // thanks to me, this is confusing
    
ThreadPool.QueueUserWorkItem(
        
delegate(object state)
        {
            
// would be true
            
Debug.WriteLine(Thread.CurrentThread.IsThreadPoolThread.ToString());
            ctx.Send(
delegate(object someState)
            {
                
// would be false
                
label1.Text = Thread.CurrentThread.IsThreadPoolThread.ToString();
            },
null);
        }
    );
}

  

Send is the method of the SynchronizationContext class to dispatch the method on the right thread synchronously. To do the same asynchronously, we call Post.

 

Another interesting thing to note is - in .NET 2.0, if you update a control on the wrong thread, you get an InvalidOperationException. As of 1.1, there was no exception, but the result was unpredicatable.

 

As you might have already guessed, there is not much documentation yet. But, unlike ContextBoundObject, ContextAttribute and other related classes, you might be seeing a lot of articles and proper documentation in the near future. At least, I shall spelunk a little more and come with an article of sorts.

Posted: Thu, Nov 3 2005 10:40 by Manoj G | with 5 comment(s)
Filed under:
Small, but useful additions in .NET 2.0 – Part 1

The BCL in .NET 2.0 has a plethora of small additions, which are not that visible, but are very useful. I’ll try to cover many of these in my subsequent posts.

 

String.IsNullOrEmpty is one such method. As the name would indicate, this method returns true if the string argument passed to this method is either null (nothing in VB) or empty.

 

VB 2005 has some good additions too. Among others, I like the IsNot operator. How much more did you want this operator after writing code like this:

 

If Not obj Is Nothing

            ..

Then

 

Now,

If  obj IsNot Nothing …looks much better.

Posted: Thu, Oct 27 2005 10:31 by Manoj G | with no comments
Filed under:
A simple MSMQ Listener helper class

MSMQ simply provides wonderful capabilities when it comes to building asynchronous messaging based applications. You typically run into situations where two applications exchange messages through a queue – one application sends messages to a known MSMQ destination and the other application “listens” to this queue and picks messages up as and when they arrive. The application which listens usually is a windows service which either has a dedicated thread making a blocking call on the Receive method or uses a timer of sorts to periodically check the queue for new messages. Either ways, to maximize throughput, you need to write the queue-listener code in such a way that you can have multiple threads simultaneously processing different messages that arrive at the queue.

MSMQ triggers provide one such solution where we can associate incoming messages to a COM component, based on certain rules, which can be application specific. MSMQ triggers are pretty powerful and also easy to administer. But there is one constraint, which has to do with the fact that only COM components are supported in this scheme, or in other words, message processors should be COM components. In a way, it isn’t that bad a choice after all. You still can create a CCW for a managed class and register the trigger. But, somehow, I didn’t like doing this. 

To circumvent this problem, I decided to write a C# helper class, which doesn’t really do anything much, but helps realize a simple multithreaded job (message processing) dispatcher. The helper itself doesn’t do any message processing as such; whenever a message arrives at a queue, it just fires an event (on a new thread pool thread) with the message contents being in the event arguments.

public delegate void MessageReceivedEventHandler(object sender, MessageEventArgs args);

public class MSMQListener
{
    
private bool _listen;
    
private Type[] _types;
    
private MessageQueue _queue;

    
public event MessageReceivedEventHandler MessageReceived;

    
public Type[] FormatterTypes
    {
        
get return _types; }
        
set { _types = value; }
    }

    
public MSMQListener(string queuePath)
    {
        _queue = 
new MessageQueue(queuePath);    
    }

    
public void Start()
    {
        _listen = 
true;
        
        
if (_types != null && _types.Length > 0)
        {
            
// Using only the XmlMessageFormatter. You can use other formatters as well
            
_queue.Formatter = new XmlMessageFormatter(_types);
        }

        _queue.PeekCompleted += 
new PeekCompletedEventHandler(OnPeekCompleted);
        _queue.ReceiveCompleted += 
new ReceiveCompletedEventHandler(OnReceiveCompleted);

        StartListening();
    }
    
    
public void Stop()
    {
        _listen = 
false;
        _queue.PeekCompleted -= 
new PeekCompletedEventHandler(OnPeekCompleted);
        _queue.ReceiveCompleted -= 
new ReceiveCompletedEventHandler(OnReceiveCompleted);

    }

    
private void StartListening()
    {
        
if (!_listen)
        {
            
return;
        }

        
// The MSMQ class does not have a BeginRecieve method that can take in a 
        // MSMQ transaction object. This is a workaround - we do a BeginPeek and then 
        // recieve the message synchronously in a transaction.
        // Check documentation for more details
        
if (_queue.Transactional)
        {
            _queue.BeginPeek();
        }
        
else
        
{
            _queue.BeginReceive();
        }
    }

    
private void OnPeekCompleted(object sender, PeekCompletedEventArgs e)
    {
        _queue.EndPeek(e.AsyncResult);
        MessageQueueTransaction trans = 
new MessageQueueTransaction();
        Message msg = 
null;
        
try
        
{
            trans.Begin();
            msg = _queue.Receive(trans);
            trans.Commit();

            StartListening();

            FireRecieveEvent(msg.Body);
        }
        
catch
        
{
            trans.Abort();
        }
    }

    
private void FireRecieveEvent(object body)
    {
        
if (MessageReceived != null)
        {
            MessageReceived(
thisnew MessageEventArgs(body));
        }
    }

    
private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
    {
        Message msg = _queue.EndReceive(e.AsyncResult);
        
        StartListening();

        FireRecieveEvent(msg.Body);
    }

}

 
public class MessageEventArgs : EventArgs
 {
    
private object _messageBody;

    
public object MessageBody
    {
        
get return _messageBody; }
    }

    
public MessageEventArgs(object body)
    {
        _messageBody = body;

    }
 }

As you can see, the helper class is indeed simple. One thing to notice though is that, I switch to BeginPeek if the queue is transactional. The reason behind this is there is no overload of the BeginRecieve method that takes a MessageQueueTransaction object and the MSDN documentation also explains the same. The workaround is to use BeginPeek and then do call Receive (synchronous/blocking operation) in the EndPeek method.

At this point of time, this class does not provide much control to the consumer. For instance, it does not allow you to set the maximum number of concurrent threads that can be processing messages - This class queues as many jobs as that supported by the .NET Thread pool. Also, I haven’t tested this code in all scenarios – I have not seen if this works well in the context of a distributed (DTC based) transaction. I shall update this version every now and then to make it more powerful and to work seamlessly in all scenarios.     

Posted: Sun, Oct 16 2005 20:00 by Manoj G | with 10 comment(s)
Filed under:
SetMaxThreads: A good addition to the ThreadPool class in 2.0

The ThreadPool class is very handy to developers. You could queue a method to run on a separate thread and forget about it, without worrying about managing the thread object or about a possible thread explosion scenario. That’s because the .NET ThreadPool keeps a tab on the number of executing threads, which I believe is a maximum of 25 per processor. This might sound just fine, but recently, I came across a situation where even 25 threads per processor looked expensive – I needed to limit the count to something like 10. Unfortunately, the ThreadPool class didn’t give me a method/property where I could set a thread count in the pool to something smaller.  I wasn’t adept enough to host the CLR, where I could tweak this count. Instead, I decided to write a simplistic wrapper over the ThreadPool class, which basically did these things:

  • Keep a count on the number of active threads (which I wanted to limit in the first place)
  • Maintain a queue to store requests is threads aren’t available
  • A timer implementation, where a thread periodically checks whether queued jobs can now be pushed to the thread pool

Quite obviously, this is a logical replica of the ThreadPool implementation itself, which is pretty wasteful. But that was until .NET Framework 1.1. In .NET 2.0, the ThreadPool class comes with this new method called SetMaxThreads – just what I craved for. You can use this to set the maximum number threads in the thread pool. There are two values to set here – one for the worker threads (which is more relevant in my case), and one for IO Port completion (this is useful for asynchronous IO operations).

Again, it is one's responsibility not to set an arbitrary high value of worker threads; Do I need to explain why?

Posted: Thu, Oct 6 2005 20:18 by Manoj G | with 3 comment(s)
Filed under:
DataSets - A journey from a boon, to a bane and back

One of the biggest cribs about the DataSet in .NET 1.0 and 1.1 was its serialization performance. The DataSet, albeit providing a rich object model to work with data in a disconnected way, was a bane when it came to passing it across tiers of the application, typically in a remoting scenario. It turned out that in this scenario, the DataSet serialization glutted on bandwidth, memory and CPU cycles. Developers who were hell bent on using the DataSet eventually became the undisputed champions of object serialization, using wonky ways to serialize the dataset in an effort to make it optimal. Less nerdy developers adopted not so adventurous means like using custom collections and arrays, but sacrificing the high-fidelity object model of the DataSet in the process.   

 

Someone said that every complex problem has a simple solution, and .NET 2.0 is turning out to be an angel to this end. As you might have already guessed, the voice from the sky is in form of a new property of the DataSet (and surprise, DataTable too) called RemotingFormat, which is an enumeration of type SerializationFormat having two members – Binary and Xml. Quite obviously, the default is Xml, to preserve backward compatibility.

 

Okay, I am digressing slightly here to note something interesting. The name of the property in discussion is RemotingFormat, not something like SerializationFormat or SerializedAs. I suppose, it is to enunciate two things:

  • DataSets (and now, even DataTable) implements IXmlSerializable, which is what the XmlSerializer looks for when serializing objects in the web service scenario. So, setting the RemotingFormat property there would be of no consequence, and it does not make sense there either.
  • Perhaps, DataSets are more apt for remoting scenarios, as compared to that of Web Services. This is not to say DataSets are deemed not usable in web services (as the implementation of IXmlSerializable would clarify). It is just that all the performance issues discussed earlier in this post would still apply in this case.

Finally, I would urge you to read this excellent article by Dino Esposito to get a better insight into this new feature and other improvements that have been added to the DataTable class as well.

Posted: Tue, Oct 4 2005 15:31 by Manoj G | with 1 comment(s)
Filed under:
Patterns in .NET : Citing the Chain of Responsibility pattern

Chain of Responsibility basically involves “chaining” a set of objects between a sender and receiver, where each object in the chain does some processing on the message that is sent between the sender and the receiver.

 

In the .NET Framework, one area where this pattern manifests is the Remoting infrastructure. In Remoting, a remote method call actually translates to a message exchange between the client and the server. When the message passes between client and the server object, it goes through a series of message sinks, which are objects which implement the IMessageSink interface. Here’s how the interface looks like (attributes have been elided for clarity):

 

public interface IMessageSink
{
      IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink);
      
      IMessage SyncProcessMessage(IMessage msg);

      IMessageSink NextSink { 
get; }
}

 

The important thing to notice here is that each message sink has a reference to the next sink in the chain. Each sink forwards the message to the next sink in the chain and the last sink to handle the message would be the StackBuilderSink. The client and the server are actually unaware of the intermediate processing; the remote call appears no different from a local (intra-appdomain) call. This scheme forms the basis of the Aspect framework built around the ContextBoundObject. In fact, I suppose, all aspect frameworks would eventually use a realization of the Chain of Responsibility pattern. 

 

PS: It has been quite a while since I posted on patterns topic and I apologize for that.

Posted: Thu, Sep 29 2005 22:24 by Manoj G | with no comments
Filed under:
Stopwatch your code!

Timing managed code is one thing I do quite often. I guess measurement of the method level execution times is a common task for any application developer for that matter. I have used various methods for measurement; the worst of them all is using DateTime. DateTime simply does not give you that high resolution timing. The alterative was to use a couple of Win32 API called QueryPerformanceCounter and QueryPerformanceFrequency. If you have used MS Enterprise Library, you would see that the Microsoft.Practices.EnterpriseLibrary.Logging.Tracing.Tracer class uses these API for timing. There is a small catch in the implementation though. Since P/Invoke is involved here, every call would result in UnManagedCode permission being demanded. The stack walk thus performed results in some loss in the resolution of the timing. Therefore, it is fair enough to mark the native method helpers with the SuppressUnmanagedCodeSecurityAttribute. This attribute ensures that the permission demand happens only at link time (JIT compile time), and not for subsequent calls. If you are well aware of the security implications of this attribute usage, you are ready to go.

 

Okay wait, don’t go far implementing all what I said earlier; System.Diagnostics.Stopwatch in .NET 2.0 gives you just that. Here’s a snippet:

 

Stopwatch watch = new Stopwatch();
watch.Start();
// Some operation
watch.Stop();
int elapsedTime = watch.ElapsedMilliseconds;

 

The best part of about the Stopwatch class is that it intelligently uses a resolution based on whether the underlying hardware supports a high one or not (QueryPerformanceFrequency API returns true if high resolution is supported). If not supported, the Stopwatch reverts to that provided by DateTime. You can query the IsHighResolution static property to find out whether high resolution is supported on your machine.  

 

Posted: Tue, Sep 27 2005 19:46 by Manoj G | with no comments
Filed under:
InternalsVisibleToAttribute - Friend Assemblies

You come across several situations where you need to develop a set of class libraries, say a framework of sorts, and there are several classes within certain assemblies which need to be marked as internal. You go ahead and mark them as internal, and then realize that there are other classes, within the framework, which are dependent on these marked classes, but exist in other assemblies. This is a problem, and you have no choice – you mark these classes as public and then document that the particular class should not be used directly from the code. You may think that this is a bad design, in a way, but there are no shortage of these in the .NET BCL. How often do you come across MSDN documentation which reads something like:

"This class supports the .NET Framework infrastructure and is not intended to be used directly from your code."?

Ideally, these should have been internal classes, but you simply cannot have them that way. StrongNameIdentityPermission provides an alternative, but it isn’t always practical. 

In .NET Framework 2.0, there exists a decent workaround to this problem. A new attribute called InternalsVisibleToAttribute has been introduced, which when applied to an assembly indicates that all internal types in that assembly would be visible to another assembly, whose name is specified in the attribute constructor. In other words, that assembly becomes a friend assembly. The usage would be something like:

[assembly:InternalsVisibleToAttribute("MyFriendAssembly”)]
Or (for a strong-named friend)
[assembly:InternalsVisibleToAttribute("MyFriendAssembly, PublicKeyToken=45cb56a45e0a69a1")]

Don’t get carried away, refer to this MSDN section to know more about the constraints and other considerations while using this attribute.

Now, what could be the usage scenarios for this attribute? I have already explained one such scenario in the earlier sections of this post. Another case may be that of unit test assemblies. Typically, we keep unit tests in separate assemblies. Now, to be able to test all the internal classes/methods, it would be useful to gain visibility into them. So, we may declare the unit-test assembly as a friend of the actual assembly.

[Digression: Adroit users of VS 2005 may quickly pounce upon the last use. VS 2005 unit testing framework provides reflection-based helpers which help you write tests against non-public members of a class. So, it’s left to you to decide which a better choice is]

Posted: Mon, Sep 26 2005 22:24 by Manoj G | with 1 comment(s)
Filed under:
Manual ADO.NET Transactions and TLS

I have come across several business and data access layer components which have method overloads taking in SqlTransaction (or IDbTransaction) references. The need here is to facilitate ADO.NET manual transactions, where database operations scattered across several components would need to be enlisted under the same transaction. Let’s assume for now that we do not want to avail the automatic transaction services of Enterprise Services or the DTC; performance being one reason, the unavoidable need to derive from System.EnterpriseServices.ServicedComponent being another. The obvious pain in the manual transaction scheme in our case is the leakage of ADO.NET objects (SqlTransaction) into the Business layer, which ideally, shouldn’t be dealing with ADO.NET specific objects at all.

 

So, what could be the solution to this problem? I thought TLS (Thread Local Storage) could be put to good avail in this case. My idea involves the following steps:

 

1) Create a helper class (call it TransactionUtils) with BeginTransaction, Commit and RollBack methods which do the work of opening and closing connections and storing transaction (SqlTransaction, for example) objects in the current thread’s named data slot. This helper would be used by the business component which forms the root of the transaction.

2) Change the data access helper (or the DAAB) to check the current thread’s slot for a transaction object and use it if it exists (append the current transaction to to the command object).  You could consider creating overloads which are ‘TLS aware’.

 

This is what TransactionHelper would look like: 

  public class TransactionHelper
    {
        
// To ensure TransactionHelper is not instantiated. All methods are static
        
private TransactionHelper()
        {
        }

        
// Name of the TLS data slot.
        
private const string TLS_SLOT_NAME = "IDbTransactionDataSlot";

        // Returns a boolean value which indicates 
        // whether current thread 
is in a transactional context
        
public static bool IsInTransaction()
        {
            
return (GetTransactionFromContext() != null);
        }
        
        // Begins an ADO.NET transaction with the specified isolation level. 
        
// Creates a TLS data slot where the transaction object would be stored
        
public static void BeginTransaction(IsolationLevel isolationLevel,  string connectionString)
        {
            
//To clear off the transaction slot, if in use
            
FreeResources(GetTransactionFromContext());
            IDbConnection conn = GetConnection(connectionString);
            IDbTransaction trans = conn.BeginTransaction(isolationLevel);
            LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot(TLS_SLOT_NAME);
            Thread.SetData(slot, trans);
        }

        // Begins an ADO.NET transaction. Creates a TLS data slot where the 
        
// transaction object would be stored
        public static void BeginTransaction(string connectionString)
        {
            
//To clear off the transaction slot, if in use
            
FreeResources(GetTransactionFromContext());
            IDbConnection conn = GetConnection(connectionString);
            IDbTransaction trans = conn.BeginTransaction();
            LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot(TLS_SLOT_NAME);
            Thread.SetData(slot, trans);
        }

        // Commits the current transaction and frees the TLS data slot
        public static void Commit()
        {
            IDbTransaction trans = GetTransactionFromContext();
            IDbConnection conn = trans.Connection;
            trans.Commit();
            conn.Dispose();
            FreeResources(trans);
        }
        
        
/// 


        /// Rolls back the current transaction and frees the TLS data slot
        
/// 

        
public static void Rollback()
        {
            IDbTransaction trans = GetTransactionFromContext();
            IDbConnection conn = trans.Connection;
            trans.Rollback();
            conn.Dispose();
            FreeResources(trans);
        }


        
// Gets an IDbTransaction object from the TLS 
        
internal static IDbTransaction GetTransactionFromContext()
        {
            LocalDataStoreSlot slot = Thread.GetNamedDataSlot(TLS_SLOT_NAME);
            
return Thread.GetData(slot) as IDbTransaction;
        }

        
// Disposes the transaction and clears the TLS slot
        
private static void FreeResources(IDbTransaction trans)
        {
            
if(trans != null)
            {
                trans.Dispose();
            }
            Thread.FreeNamedDataSlot(TLS_SLOT_NAME);
        }

        
// Gets a connection object 
        
private static IDbConnection GetConnection(string connectionString)
        {
            IDbConnection conn = SqlHelper.GetConnection(connectionString);
            conn.Open();
            
return conn;
        }

    }

So, the snippet of a business component which uses the TransactionHelper would look something like:

class MyBizComp
{

    
public void DoSomeOperation()
    {
        
try
        
{
            TransactionHelper.BeginTransaction(connectionString);
            
// Call other biz components, they would get enlisted within
            // the same transaction
            
TransactionHelper.Commit();
        }
        
catch
        
{
            TransactionHelper.Rollback();
        }
        
finally
        
{
            
// Cleanup    
        
}
    }  
}

So, we have a solution here, which is not that elegant, but atleast, sheilds the business layer from the nuances of ADO.NET. Note that the assumption here is that all the other business components eventually call those methods in the data access layer which are context (TLS) aware.

Two important things to note regarding this approach:

1) The connection is kept open (behind the scenes) during the period between the BeginTran and Commit, and therefore during the execution of all the business components that are enlisted in a single transaction. So, it is imperative to keep transaction bracket as small as possible to improve concurrency.

2) This methodology does not work in a multithreaded scenario, where different components in the call chain happen to execute on different threads. Obviously, because TLS is thread specific.

Another similar implementation you may want to look into is the transaction helper in Juval Lowy’s site, IDesign.Net, where you have a helper class which does something similar, but wraps Enterprise Services. 

Come .NET 2.0, System.Transactions provides an elegant way to “scope” a transaction in the business layer. Not so surprisingly, the current transaction (Ambient transaction) is persisted in the TLS. System.Transactions is one of the coolest new things in .NET 2.0 and will be the subject of another post altogether.

Posted: Sun, Sep 18 2005 19:24 by Manoj G | with 1 comment(s)
Filed under:
More Posts Next page »