diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SNS/CachedMessageHeadersHelper.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SNS/CachedMessageHeadersHelper.cs
index e7721a9607a0..d06524b24735 100644
--- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SNS/CachedMessageHeadersHelper.cs
+++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SNS/CachedMessageHeadersHelper.cs
@@ -12,17 +12,27 @@
using System.Text;
using Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Shared;
using Datadog.Trace.DuckTyping;
+using Datadog.Trace.Util;
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS
{
+ ///
+ /// Allows the creation of MessageAttributes and MessageAttributeValue with a type corresponding to the one given as template parameter
+ ///
+ /// can be any type in the same assembly as the Attributes we want to create.
internal sealed class CachedMessageHeadersHelper : IMessageHeadersHelper
{
+ // We have to use Binary for SNS because passing JSON payloads with String type makes subscription filter policies fail silently.
+ // see https://github.com/DataDog/datadog-lambda-js/pull/269 for more details.
private const string StringDataType = "Binary";
- private static readonly Func _createMessageAttributeValue;
- private static readonly Func _createDict;
+ // ReSharper disable StaticMemberInGenericType
+ // there will be one instance of those fields per template type
+ private static readonly Func MessageAttributeValueCreator;
+ private static readonly ActivatorHelper DictionaryActivator;
+ // ReSharper restore StaticMemberInGenericType
- public static readonly CachedMessageHeadersHelper Instance = new();
+ public static readonly CachedMessageHeadersHelper Instance;
private CachedMessageHeadersHelper()
{
@@ -54,37 +64,24 @@ static CachedMessageHeadersHelper()
messageAttributeIL.Emit(OpCodes.Ret);
- _createMessageAttributeValue = (Func)createMessageAttributeValueMethod.CreateDelegate(typeof(Func));
+ MessageAttributeValueCreator = (Func)createMessageAttributeValueMethod.CreateDelegate(typeof(Func));
// Initialize delegate for creating a Dictionary object
- var genericDictType = typeof(Dictionary<,>);
- var constructedDictType = genericDictType.MakeGenericType(new Type[] { typeof(string), messageAttributeValueType });
- ConstructorInfo dictionaryCtor = constructedDictType.GetConstructor(System.Type.EmptyTypes);
+ DictionaryActivator = new ActivatorHelper(typeof(Dictionary<,>).MakeGenericType(typeof(string), messageAttributeValueType));
- DynamicMethod createDictMethod = new DynamicMethod(
- $"SnsCachedMessageHeadersHelpers",
- constructedDictType,
- null,
- typeof(DuckType).Module,
- true);
-
- ILGenerator dictIL = createDictMethod.GetILGenerator();
- dictIL.Emit(OpCodes.Newobj, dictionaryCtor);
- dictIL.Emit(OpCodes.Ret);
-
- _createDict = (Func)createDictMethod.CreateDelegate(typeof(Func));
+ Instance = new CachedMessageHeadersHelper();
}
public IDictionary CreateMessageAttributes()
{
- return _createDict();
+ return (IDictionary)DictionaryActivator.CreateInstance();
}
public object CreateMessageAttributeValue(string value)
{
var bytes = Encoding.UTF8.GetBytes(value);
var stream = new MemoryStream(bytes);
- return _createMessageAttributeValue(stream);
+ return MessageAttributeValueCreator(stream);
}
}
}
diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SQS/CachedMessageHeadersHelper.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SQS/CachedMessageHeadersHelper.cs
index 67a6d774f015..93a1cee8ec90 100644
--- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SQS/CachedMessageHeadersHelper.cs
+++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/SQS/CachedMessageHeadersHelper.cs
@@ -13,14 +13,21 @@
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS
{
+ ///
+ /// Allows the creation of MessageAttributes and MessageAttributeValue with a type corresponding to the one given as template parameter
+ ///
+ /// can be any type in the same assembly as the Attributes we want to create.
internal sealed class CachedMessageHeadersHelper : IMessageHeadersHelper
{
private const string StringDataType = "String";
- private static readonly Func _createMessageAttributeValue;
+ // ReSharper disable StaticMemberInGenericType
+ // there will be one instance of those fields per template type
+ private static readonly Func MessageAttributeValueCreator;
private static readonly ActivatorHelper DictionaryActivator;
+ // ReSharper restore StaticMemberInGenericType
- public static readonly CachedMessageHeadersHelper Instance = new();
+ public static readonly CachedMessageHeadersHelper Instance;
private CachedMessageHeadersHelper()
{
@@ -52,10 +59,12 @@ static CachedMessageHeadersHelper()
messageAttributeIL.Emit(OpCodes.Ret);
- _createMessageAttributeValue = (Func)createMessageAttributeValueMethod.CreateDelegate(typeof(Func));
+ MessageAttributeValueCreator = (Func)createMessageAttributeValueMethod.CreateDelegate(typeof(Func));
// Initialize delegate for creating a Dictionary object
DictionaryActivator = new ActivatorHelper(typeof(Dictionary<,>).MakeGenericType(typeof(string), messageAttributeValueType));
+
+ Instance = new CachedMessageHeadersHelper();
}
public IDictionary CreateMessageAttributes()
@@ -65,7 +74,7 @@ public IDictionary CreateMessageAttributes()
public object CreateMessageAttributeValue(string value)
{
- return _createMessageAttributeValue(value);
+ return MessageAttributeValueCreator(value);
}
}
}