Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core equivalent of CallContext.LogicalGet/SetData

I am trying to move into .net core an existing .net application that is using CallContext.LogicalGet/SetData.

When a web request hits the application I save a CorrelationId in the CallContext and whenever I need to log something later down the track I can easily collect it from the CallContext, without the need to transfer it everywhere.

As CallContext is no longer supported in .net core since it is part of System.Messaging.Remoting what options are there?

One version I have seen is that the AsyncLocal could be used (How do the semantics of AsyncLocal differ from the logical call context?) but it looks as if I would have to transmit this variable all over which beats the purpose, it is not as convenient.

like image 969
Gradinariu Cezar Avatar asked Feb 15 '17 06:02

Gradinariu Cezar


People also ask

Is .NET Core in C#?

NET Core platform such as mobile, desktop, web, cloud, IoT, machine learning, microservices, game, etc. Supports Multiple Languages: You can use C#, F#, and Visual Basic programming languages to develop .

Is the base library for .NET Core?

NET Core, you can build cross-platform console apps and ASP.NET Core Web applications and cloud services. . NET Standard: This is the set of fundamental APIs (commonly referred to as base class library or BCL) that all .

What is call context in C#?

CallContext is a specialized collection object similar to a Thread Local Storage for method calls and provides data slots that are unique to each logical thread of execution. The slots are not shared across call contexts on other logical threads.

Can you mix .NET Core and .NET framework?

At this point, if your NuGet dependencies are compatible with both your netcore and netframework targets you may be done! The big news here is that most of your NuGet dependencies are compatible with both. All of the most downloaded NuGet packages are either multi-targeted, or have packages for each target.


2 Answers

Had this problem when we switched a library from .Net Framework to .Net Standard and had to replace System.Runtime.Remoting.Messaging CallContext.LogicalGetData and CallContext.LogicalSetData.

I followed this guide to replace the methods:

http://www.cazzulino.com/callcontext-netstandard-netcore.html

/// <summary>
/// Provides a way to set contextual data that flows with the call and 
/// async context of a test or invocation.
/// </summary>
public static class CallContext
{
    static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();

    /// <summary>
    /// Stores a given object and associates it with the specified name.
    /// </summary>
    /// <param name="name">The name with which to associate the new item in the call context.</param>
    /// <param name="data">The object to store in the call context.</param>
    public static void SetData(string name, object data) =>
        state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;

    /// <summary>
    /// Retrieves an object with the specified name from the <see cref="CallContext"/>.
    /// </summary>
    /// <param name="name">The name of the item in the call context.</param>
    /// <returns>The object in the call context associated with the specified name, or <see langword="null"/> if not found.</returns>
    public static object GetData(string name) =>
        state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
}
like image 182
Ogglas Avatar answered Oct 19 '22 16:10

Ogglas


You can use a dictionary of AsyncLocal to simulate exactly the API and behavior of the original CallContext. See http://www.cazzulino.com/callcontext-netstandard-netcore.html for a complete implementation example.

like image 16
kzu Avatar answered Oct 19 '22 16:10

kzu