Skip to content

Commit 7e59c23

Browse files
sandst1Pliner
authored andcommitted
Make GetSupersededType work with any message version hierarchy (#902)
MessageVersionStack.GetSupersededType uses Type.GetInterfaces which does not offer any order guarantees. When selecting the superseded type for a message, we could sort by class name, but that would just introduce a limitation on message naming. Instead of that, let's call GetInterfaces for type and type.BaseType, and grab the ISupersede entries from those. The one that does not exist in base type's list is the correct superseded type.
1 parent 487a4db commit 7e59c23

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

Source/EasyNetQ.Tests/MessageVersioningTests/MessageVersionStackTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ public void Versioned_message_stack_works_for_more_than_two_versions_and_types_a
3535
Assert.Equal(typeof(MyMessageV3), stack.ElementAt( 2 ));
3636
}
3737

38+
[Fact]
39+
public void Versioned_message_stack_works_with_arbitrary_type_names()
40+
{
41+
var stack = new MessageVersionStack( typeof( ComplexMessage ));
42+
43+
Assert.Equal(typeof(SimpleMessage), stack.ElementAt( 0 ));
44+
Assert.Equal(typeof(AdvancedMessage), stack.ElementAt( 1 ));
45+
Assert.Equal(typeof(ComplexMessage), stack.ElementAt( 2 ));
46+
}
47+
48+
[Fact]
49+
public void If_given_just_an_object_the_stack_can_handle_it_without_exceptions()
50+
{
51+
var stack = new MessageVersionStack( typeof( object ));
52+
53+
Assert.Equal(typeof(object), stack.ElementAt( 0 ));
54+
}
55+
3856
[Fact]
3957
public void Pop_returns_the_top_of_the_stack()
4058
{
@@ -73,4 +91,19 @@ public class MyOtherMessage : MyMessage, ISupersede<MyMessageV2>
7391
{
7492
public int AnotherNumber { get; set; }
7593
}
94+
95+
public class SimpleMessage
96+
{
97+
public string Message { get; set; }
98+
}
99+
100+
public class AdvancedMessage : SimpleMessage, ISupersede<SimpleMessage>
101+
{
102+
public string VeryAdvanced { get; set; }
103+
}
104+
105+
public class ComplexMessage : AdvancedMessage, ISupersede<AdvancedMessage>
106+
{
107+
public string SoComplex { get; set; }
108+
}
76109
}

Source/EasyNetQ/MessageVersioning/MessageVersionStack.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,21 @@ private static Stack<Type> ExtractMessageVersions( Type type )
5656

5757
private static Type GetSupersededType( Type type )
5858
{
59-
return type
59+
if( type.BaseType == null )
60+
return null;
61+
62+
var types = FindSupersedes(type);
63+
var parentTypes = FindSupersedes(type.BaseType);
64+
65+
return types.Except(parentTypes).FirstOrDefault();
66+
}
67+
68+
private static IEnumerable<Type> FindSupersedes( Type type )
69+
{
70+
return type
6071
.GetInterfaces()
6172
.Where( t => t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == typeof( ISupersede<> ) )
62-
.SelectMany( t => t.GetGenericArguments() )
63-
.LastOrDefault();
73+
.SelectMany( t => t.GetGenericArguments() );
6474
}
6575

6676
private static void EnsureVersioningValid( Type messageType, Type supersededType )

0 commit comments

Comments
 (0)