Living .NET...

Musings on .NET, and the like - Manoj G [MVP, Connected Systems Developer]

September 2005 - Posts

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: