Correlation Id Scope

A correlation id is an enterprise messaging pattern that helps bind together several messages. If they have the same correlation id, then they must be somehow related. Several servers and service bus frameworks, such as SharePoint and NServiceBus, use this concept.

We need correlation ids to be unique and apply to possibly several messages. I have been using a correlation scope class, presented below, to make sure of this:

public sealed class CorrelationScope : IDisposable

{

    [ThreadStatic]

    private static string correlationId;

    [ThreadStatic]

    private static CorrelationScope creator;

 

    private readonly Func<object> generator = () => Guid.NewGuid();

 

    public CorrelationScope(Func<object> gen)

    {

        if (correlationId == null)

        {

            this.generator = gen ?? this.generator;

            correlationId = this.generator().ToString();

            creator = this;

        }

    }

 

    public CorrelationScope() : this(null)

    {

    }

 

    public static string Current

    {

        get

        {

            return correlationId;

        }

    }

 

    void IDisposable.Dispose()

    {

        if (creator == this)

        {

            creator = null;

            correlationId = null;

        }

    }

}

A regular usage would be:

void AnotherFunc()

{

    using (new CorrelationScope())

    {

        var correlationId = CorrelationScope.Current;    //same as before

        //...

    }

}

 

void SomeFunc()

{

    using (new CorrelationScope())

    {

        var correlationId = CorrelationScope.Current;

        AnotherFunc();

 

        using (new CorrelationScope())

        {

            correlationId = CorrelationScope.Current;    //same as before

        }

    }

}

So, what we have is:

  • We instantiate a CorrelationScope instance, probably inside a using block; this will delimit the boundaries of our scope;
  • If no generator function is supplied, it uses Guid.NewGuid;
  • The scope will be unique per thread, regardless of the call stack, the current value will always be returned;
  • Nested CorrelationScopes will still retain the current value.

This pattern is also used by the TransactipnScope and Transaction.Current, but TransactipnScope allows starting a new scope or aborting if one already exists.

Well, it’s a simple thing, but maybe someone can find use for it! Winking smile

Published by

Ricardo Peres

Team Leader at Dixons Carphone. Microsoft MVP.

Leave a Reply

Your email address will not be published. Required fields are marked *