A better context container

Suppose you want to share some context info between multiple methods / objects. In WCF you must use OperationContext.Current to store the data. In ASP.Net, you can use the session, or better the HttpContext.Items. For Windows Forms, you will have the ThreadStatic attribute. With my new implementation of an AmbientContext, we have a single store to share the context data in all of theses scenarios.

I've picked the idea here:

http://aabs.wordpress.com/2007/12/31/the-ambient-context-design-pattern-in-net/

and here:

http://msdn.microsoft.com/msdnmag/issues/06/09/NETMatters/default.aspx

OK, here is a sample code to use it:

public void Method1()
{
using (new AmbientContextScope())
{
AmbientContext.Current.SetLogicalValue(
"userInfo",
new UserInfo()
{
DisplayName = "Dany Laporte",
Username = "danlap"
});

this.ShowUserInContext();
}
}

public void ShowUserInContext()
{
if (AmbientContext.Current != null)
{
UserInfo userInfo = (UserInfo)AmbientContext.Current.GetLogicalValue("userInfo");
Console.WriteLine(userInfo.DisplayName);
}
}

With a context scope, you can copy the data upon multiple contexts or multiple threads easily. You can also create delegate that are scoped based on the current context.


using (new AmbientContextScope())
{
AmbientContext.Current.SetLogicalValue("myKey", "myValue");

ThreadPool.QueueUserWorkItem(
AmbientContext.Current.CreateScopedDelegate(
delegate(object state)
{
Console.WriteLine(AmbientContext.Current.GetLogicalValue("myKey"));
}));
}

Here is a simple class diagram of the actual implementation:



AmbientContextDiagram

Please tell me what you think?

Pourquoi on ne devrait pas utiliser l'héritage de classe

Voici un article intéressant décrivant une facette négative de l'héritage de classe. http://www.berniecode.com/writing/inheritance/

C# 3.0 - Méthodes d'extensions et exceptions

Pour ceux et celles qui commencent à utiliser le C# 3.0, vous avez sans doute commencé à utiliser les méthodes d'extensions. Cette nouvelle possibilité nous permet maintenant d'étendre les classes, structures et interfaces en leur ajoutant de nouvelles méthodes.

Aujourd'hui, j'aimerais utiliser les méthodes d'extensions afin de pouvoir réduire le code pour lever des exceptions. La plupart d'entre nous, lorsque nous voulons lever une exception, nous écrivons le code suivant:

public Employee CreateEmployee(string employeeNumber)
{
if (employeeNumber == null)
throw new ArgumentNullException("employeeNumber");

if (employeeNumber.Length == 0)
throw new ArgumentException(string.Format(Properties.Resources.ArgumentStringCannotBeEmtpy, "employeeNumber"), "employeeNumber");

return new Employee(employeeNumber);
}



Ce code très simple mais est souvent redondant et tellement long à écrire que certain programmeur préfère omettre ce code et ne pas lever d'exceptions.



J'ai décidé de me pencher sur le problème et d'essayer de trouver une solution pour écrire moins de code. Voici la solution que je propose:



public Employee CreateEmployee(string employeeNumber)
{
employeeNumber.Check("employeeNumber").ThrowNull().ThrowEmpty();
return new Employee(employeeNumber);
}


C'est beaucoup plus compact et permet de réutiliser le code qui lève les exceptions. La méthode d'extension Check est ajoutée à tous les types de classe et permet d'introduire le nom du paramètre à vérifier. Ensuite, le ThrowNull (réservé aux classes) lève un ArgumentNullException si le paramètre est null. Le ThrowEmpty (réservé aux Strings) lève le ArgumentException.


Qu'en pensez-vous?


Il est possible de pousser les validations encore plus loin et d'ajouter des lambdas. J'en parlerai dans un prochain billet. A+


Dany.