diff --git a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
index c544c4d70c..dbc50a6607 100644
--- a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
@@ -7,3 +7,4 @@
[assembly: SuppressMessage("Design", "CA1052:Static holder types should be Static or NotInheritable", Justification = "Previously released as non-static / inheritable", Scope = "type", Target = "~T:Microsoft.IdentityModel.Logging.LogHelper")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Execution should not be altered for exceptions on format", Scope = "member", Target = "~M:Microsoft.IdentityModel.Logging.IdentityModelEventSource.PrepareMessage(System.Diagnostics.Tracing.EventLevel,System.String,System.Object[])~System.String")]
+[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Logging.LoggerContext.PropertyBag")]
diff --git a/src/Microsoft.IdentityModel.Logging/LoggerContext.cs b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs
new file mode 100644
index 0000000000..77481be63e
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.IdentityModel.Logging
+{
+ ///
+ /// A context class that can be used to store work per request to aid with debugging.
+ ///
+ public class LoggerContext
+ {
+ ///
+ /// Instantiates a new with the default activityId.
+ ///
+ public LoggerContext()
+ {
+ }
+
+ ///
+ /// Instantiates a new with an activityId.
+ ///
+ ///
+ public LoggerContext(Guid activityId)
+ {
+ ActivityId = activityId;
+ }
+
+ ///
+ /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging.
+ ///
+ public Guid ActivityId { get; set; } = Guid.Empty;
+
+ ///
+ /// Gets or sets a boolean controlling if logs are written into the context.
+ /// Useful when debugging.
+ ///
+ public bool CaptureLogs { get; set; } = false;
+
+ ///
+ /// Gets or sets a string that helps with setting breakpoints when debugging.
+ ///
+ public string Id { get; set; } = string.Empty;
+
+ ///
+ /// The collection of logs associated with a request. Use to control capture.
+ ///
+ public ICollection Logs { get; private set; } = new Collection();
+
+ ///
+ /// Gets or sets an that enables custom extensibility scenarios.
+ ///
+ public IDictionary PropertyBag { get; set; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/CallContext.cs b/src/Microsoft.IdentityModel.Tokens/CallContext.cs
index 5e1195377d..d800d7dd05 100644
--- a/src/Microsoft.IdentityModel.Tokens/CallContext.cs
+++ b/src/Microsoft.IdentityModel.Tokens/CallContext.cs
@@ -26,50 +26,27 @@
//------------------------------------------------------------------------------
using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
+using Microsoft.IdentityModel.Logging;
namespace Microsoft.IdentityModel.Tokens
{
///
/// An opaque context used to store work when working with authentication artifacts.
///
- public class CallContext
+ public class CallContext : LoggerContext
{
///
/// Instantiates a new with a default activityId.
///
- public CallContext()
+ public CallContext() : base()
{
}
///
/// Instantiates a new with an activityId.
///
- public CallContext(Guid activityId)
+ public CallContext(Guid activityId) : base(activityId)
{
- ActivityId = activityId;
}
-
- ///
- /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging.
- ///
- public Guid ActivityId { get; set; } = Guid.Empty;
-
- ///
- /// Gets or sets a boolean controlling if logs are written into the context.
- /// Useful when debugging.
- ///
- public bool CaptureLogs { get; set; } = false;
-
- ///
- /// The collection of logs associated with a request. Use to control capture.
- ///
- public ICollection Logs { get; private set; } = new Collection();
-
- ///
- /// Gets or sets an that enables custom extensibility scenarios.
- ///
- public IDictionary PropertyBag { get; set; }
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
index 83ef0e0a80..86381917d7 100644
--- a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
@@ -24,7 +24,6 @@
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.AdditionalHeaderClaims")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.Claims")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.JsonWebKey.Oth")]
-[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.CallContext.PropertyBag")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking chnage", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.TokenValidationParameters.PropertyBag")]
[assembly: SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Current design", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.TokenValidationParameters.#ctor(Microsoft.IdentityModel.Tokens.TokenValidationParameters)")]
[assembly: SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through ReleaseSignatureProvider", Scope = "member", Target = "~F:Microsoft.IdentityModel.Tokens.AuthenticatedEncryptionProvider._symmetricSignatureProvider")]
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs
new file mode 100644
index 0000000000..50a5e1ec63
--- /dev/null
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.CodeDom;
+using Microsoft.IdentityModel.Logging;
+using Microsoft.IdentityModel.TestUtils;
+using Xunit;
+
+#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
+
+namespace Microsoft.IdentityModel.Tokens.Tests
+{
+ public class CallContextTests
+ {
+ [Theory, MemberData(nameof(CallContextTestTheoryData))]
+ public void LoggerInstanceTests(CallContextTheoryData theoryData)
+ {
+ var context = new CallContext(theoryData.ActivityId) { Id = theoryData.TestId };
+
+ Assert.IsAssignableFrom(context);
+ Assert.Equal(theoryData.TestId, context.Id);
+ Assert.Equal(theoryData.ActivityId, context.ActivityId);
+ Assert.False(context.CaptureLogs);
+ Assert.Empty(context.Logs);
+ Assert.Null(context.PropertyBag);
+ }
+
+ public static TheoryData CallContextTestTheoryData
+ {
+ get
+ {
+ var theoryData = new TheoryData();
+
+ theoryData.Add(new CallContextTheoryData
+ {
+ TestId = "abdc",
+ ActivityId = new Guid()
+ });
+
+ return theoryData;
+ }
+ }
+ }
+
+ public class CallContextTheoryData : TheoryDataBase
+ {
+ public Guid ActivityId;
+ }
+}
+
+#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant