Skip to content

Commit c12d359

Browse files
Allow using nullable complex types (and arrays) in the message types (#6004)
1 parent a8215bf commit c12d359

4 files changed

Lines changed: 35 additions & 13 deletions

File tree

src/NServiceBus.Core.Tests/MessageMapper/MessageMapperTests.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,29 @@ public void CreateInstance_WhenMessageInitialized_ShouldBeThreadsafe()
4646
});
4747
}
4848

49+
#if NETCOREAPP
50+
#nullable enable
4951
[Test]
5052
public void Should_handle_messages_with_nullable_reference_types()
5153
{
5254
var mapper = new MessageMapper();
5355

54-
// Type defined in separate assembly as a workaround
55-
// because we can't use nullable refeference types yet
56-
mapper.CreateInstance<WithDodgyNullable.IMyMessage>();
56+
mapper.CreateInstance<IMessageWithNullableProperties>();
5757
}
5858

59+
public interface IMessageWithNullableProperties : NServiceBus.ICommand, NServiceBus.IMessage
60+
{
61+
string? NullableString { get; set; }
62+
object[]? NullableArray { get; set; }
63+
List<NullableComplexTypeItem>? NullableList { get; set; }
64+
}
65+
66+
public class NullableComplexTypeItem
67+
{
68+
}
69+
#nullable disable
70+
#endif
71+
5972
[Test]
6073
public void CreateInstance_WhenMessageNotInitialized_ShouldBeThreadsafe()
6174
{
@@ -253,5 +266,6 @@ public interface IMessageInterfaceWithNullablePropertyAttribute
253266
object Value { get; set; }
254267
}
255268

269+
256270
}
257271
}

src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
<Reference Include="System.Transactions" />
1717
</ItemGroup>
1818

19-
<!-- Workaround reference because we can't use nullable reference types yet -->
20-
<ItemGroup>
21-
<Reference Include="WithDodgyNullable" HintPath="TestDlls\WithDodgyNullable.dll" />
22-
</ItemGroup>
23-
<!-- End workaround -->
24-
2519
<ItemGroup>
2620
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
2721
<PackageReference Include="Mono.Cecil" Version="0.10.4" />
-6 KB
Binary file not shown.

src/NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection/ConcreteProxyCreator.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace NServiceBus
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Collections.ObjectModel;
56
using System.Linq;
67
using System.Reflection;
78
using System.Reflection.Emit;
@@ -99,26 +100,39 @@ static void AddCustomAttributeToProperty(CustomAttributeData attributeData, Prop
99100
{
100101
var namedArguments = attributeData.NamedArguments;
101102

103+
object[] constructorArgs = attributeData.ConstructorArguments.Select(ExtractValue).ToArray();
102104
if (namedArguments == null)
103105
{
104106
var attributeBuilder = new CustomAttributeBuilder(
105107
attributeData.Constructor,
106-
attributeData.ConstructorArguments.Select(x => x.Value).ToArray());
108+
constructorArgs);
107109

108110
propBuilder.SetCustomAttribute(attributeBuilder);
109111
}
110112
else
111113
{
114+
PropertyInfo[] namedProperties = namedArguments.Select(x => (PropertyInfo)x.MemberInfo).ToArray();
115+
object[] propertyValues = namedArguments.Select(x => x.TypedValue.Value).ToArray();
116+
112117
var attributeBuilder = new CustomAttributeBuilder(
113118
attributeData.Constructor,
114-
attributeData.ConstructorArguments.Select(x => x.Value).ToArray(),
115-
namedArguments.Select(x => (PropertyInfo)x.MemberInfo).ToArray(),
116-
namedArguments.Select(x => x.TypedValue.Value).ToArray());
119+
constructorArgs,
120+
namedProperties,
121+
propertyValues);
117122

118123
propBuilder.SetCustomAttribute(attributeBuilder);
119124
}
120125
}
121126

127+
static object ExtractValue(CustomAttributeTypedArgument arg)
128+
{
129+
if (arg.Value is ReadOnlyCollection<CustomAttributeTypedArgument> nestedValue)
130+
{
131+
return nestedValue.Select(x => x.Value).ToArray();
132+
}
133+
return arg.Value;
134+
}
135+
122136
/// <summary>
123137
/// Returns all properties on the given type, going up the inheritance hierarchy.
124138
/// </summary>

0 commit comments

Comments
 (0)