.NET Core эквивалент CallContext.LogicalGet/SetData

Я пытаюсь переместить в ядро ​​.net существующее приложение.net, которое использует CallContext.LogicalGet/SetData.

Когда веб-запрос попадает в приложение, я сохраняю CorrelationId в CallContext, и всякий раз, когда мне нужно что-то записать позже, я могу легко собрать это из CallContext без необходимости передавать его повсюду.

Поскольку CallContext больше не поддерживается в ядре.net, так как он является частью System.Messaging.Remoting, какие варианты есть?

Одна версия, которую я видел, состоит в том, что AsyncLocal можно использовать ( Чем семантика AsyncLocal отличается от контекста логического вызова?), Но выглядит так, как будто мне придется передавать всю эту переменную, которая превосходит цель, это не так удобный.

3 ответа

Была эта проблема, когда мы переключили библиотеку с.Net Framework на.Net Standard и пришлось заменить System.Runtime.Remoting.MessagingCallContext.LogicalGetData а также CallContext.LogicalSetData,

Я следовал этому руководству, чтобы заменить методы:

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;
}

Вы можете использовать словарь AsyncLocal для имитации точно API и поведения исходного CallContext. См. http://www.cazzulino.com/callcontext-netstandard-netcore.html для полного примера реализации.

Я предполагаю, что вы могли бы использовать ThreadStatic, поскольку то, что я слышал, CallContext является "просто" абстракцией над ThreadStatic с автоматической передачей состояния между потоками в стеке вызовов.

Кроме того, вы можете / должны использовать AsyncLocal/ThreadLocal вместо этого. AsyncLocal, кажется, в значительной степени то, что CallContext был.

Другие вопросы по тегам