diff --git a/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_greedy_convention.cs b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_greedy_convention.cs new file mode 100644 index 00000000000..c0320ddaf44 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_greedy_convention.cs @@ -0,0 +1,64 @@ +namespace NServiceBus.AcceptanceTests.BasicMessaging +{ + using System; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + using ScenarioDescriptors; + + public class When_using_a_greedy_convention : NServiceBusAcceptanceTest + { + [Test] + public void Should_receive_the_message() + { + Scenario.Define(() => new Context { Id = Guid.NewGuid() }) + .WithEndpoint(b => b.Given((bus, context) => bus.SendLocal(new MyMessage + {Id = context.Id}))) + .Done(c => c.WasCalled) + .Repeat(r =>r + .For(Transports.Msmq) + ) + .Should(c => Assert.True(c.WasCalled, "The message handler should be called")) + .Run(); + } + + public class Context : ScenarioContext + { + public bool WasCalled { get; set; } + + public Guid Id { get; set; } + } + + public class EndPoint : EndpointConfigurationBuilder + { + public EndPoint() + { + EndpointSetup(c => c.DefiningMessagesAs(MessageConvention)); + } + + static bool MessageConvention(Type t) + { + return t.Namespace != null && + (t.Namespace.EndsWith(".Messages") || (t == typeof(MyMessage))); + } + } + + [Serializable] + public class MyMessage + { + public Guid Id { get; set; } + } + + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + public void Handle(MyMessage message) + { + if (Context.Id != message.Id) + return; + + Context.WasCalled = true; + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index add5476ccbc..f631b1ed95f 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -99,6 +99,7 @@ + diff --git a/src/NServiceBus.Core.Tests/MessageConventionExtensionsTests.cs b/src/NServiceBus.Core.Tests/MessageConventionExtensionsTests.cs index 9e0a59a107a..87d844a861e 100644 --- a/src/NServiceBus.Core.Tests/MessageConventionExtensionsTests.cs +++ b/src/NServiceBus.Core.Tests/MessageConventionExtensionsTests.cs @@ -1,6 +1,9 @@ -namespace NServiceBus.Core.Tests.Encryption +namespace NServiceBus.Core.Tests { using System; + using System.Reflection; + using System.Reflection.Emit; + using Unicast.Messages; using NUnit.Framework; [TestFixture] @@ -12,6 +15,7 @@ public void Should_use_TimeToBeReceived_from_bottom_of_tree() var timeToBeReceivedAction = MessageConventionExtensions.TimeToBeReceivedAction(typeof(InheritedClassWithAttribute)); Assert.AreEqual(TimeSpan.FromSeconds(2), timeToBeReceivedAction); } + [Test] public void Should_use_inherited_TimeToBeReceived() { @@ -32,6 +36,38 @@ class InheritedClassWithNoAttribute : BaseClass { } + + + [Test] + public void Should_return_false_for_SN_and_non_particular_assembly() + { + Assert.IsFalse(MessageConventionExtensions.IsFromParticularAssembly(typeof(string))); + } + + [Test] + public void Should_return_true_for_particular_assembly() + { + Assert.IsTrue(MessageConventionExtensions.IsFromParticularAssembly(typeof(ExecuteLogicalMessagesBehavior))); + } + + [Test] + public void Should_return_false_for_non_SN_and_non_particular_assembly() + { + var type = GetNonSnFakeType(); + Assert.IsFalse(MessageConventionExtensions.IsFromParticularAssembly(type)); + } + + static Type GetNonSnFakeType() + { + var assemblyName = new AssemblyName + { + Name = "myAssembly" + }; + var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.ReflectionOnly); + var newModule = assemblyBuilder.DefineDynamicModule("myModule"); + var myType = newModule.DefineType("myType", TypeAttributes.Public); + return myType.CreateType(); + } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj index a3a03b3aa30..81c29e53f97 100644 --- a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj +++ b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj @@ -13,6 +13,8 @@ 512 true ..\NServiceBus.snk + Test.snk + ..\ true @@ -310,6 +312,7 @@ Designer + diff --git a/src/NServiceBus.Core.Tests/Test.snk b/src/NServiceBus.Core.Tests/Test.snk new file mode 100644 index 00000000000..59da17bf7e1 Binary files /dev/null and b/src/NServiceBus.Core.Tests/Test.snk differ diff --git a/src/NServiceBus.Core/InternalsVisibleTo.cs b/src/NServiceBus.Core/InternalsVisibleTo.cs index 72629155ee0..b21f489ac3c 100644 --- a/src/NServiceBus.Core/InternalsVisibleTo.cs +++ b/src/NServiceBus.Core/InternalsVisibleTo.cs @@ -1,4 +1,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("NServiceBus.Hosting.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100dde965e6172e019ac82c2639ffe494dd2e7dd16347c34762a05732b492e110f2e4e2e1b5ef2d85c848ccfb671ee20a47c8d1376276708dc30a90ff1121b647ba3b7259a6bc383b2034938ef0e275b58b920375ac605076178123693c6c4f1331661a62eba28c249386855637780e3ff5f23a6d854700eaa6803ef48907513b92")] -[assembly: InternalsVisibleTo("NServiceBus.Core.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100dde965e6172e019ac82c2639ffe494dd2e7dd16347c34762a05732b492e110f2e4e2e1b5ef2d85c848ccfb671ee20a47c8d1376276708dc30a90ff1121b647ba3b7259a6bc383b2034938ef0e275b58b920375ac605076178123693c6c4f1331661a62eba28c249386855637780e3ff5f23a6d854700eaa6803ef48907513b92")] \ No newline at end of file +[assembly: InternalsVisibleTo("NServiceBus.Core.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001007f16e21368ff041183fab592d9e8ed37e7be355e93323147a1d29983d6e591b04282e4da0c9e18bd901e112c0033925eb7d7872c2f1706655891c5c9d57297994f707d16ee9a8f40d978f064ee1ffc73c0db3f4712691b23bf596f75130f4ec978cf78757ec034625a5f27e6bb50c618931ea49f6f628fd74271c32959efb1c5")] \ No newline at end of file diff --git a/src/NServiceBus/MessageConventionExtensions.cs b/src/NServiceBus/MessageConventionExtensions.cs index 89226bcbff5..67afad48e43 100644 --- a/src/NServiceBus/MessageConventionExtensions.cs +++ b/src/NServiceBus/MessageConventionExtensions.cs @@ -11,6 +11,21 @@ /// public static class MessageConventionExtensions { + static byte[] nsbPublicKeyToken; + + static MessageConventionExtensions() + { + var currentAssemblyName = typeof(MessageConventionExtensions).Assembly.GetName(); + nsbPublicKeyToken = currentAssemblyName.GetPublicKeyToken(); + } + + internal static bool IsFromParticularAssembly(Type type) + { + return type.Assembly.GetName() + .GetPublicKeyToken() + .SequenceEqual(nsbPublicKeyToken); + } + /// /// Returns true if the given object is a message. /// @@ -27,10 +42,20 @@ public static bool IsMessageType(Type t) try { return MessagesConventionCache.ApplyConvention(t, - type => IsMessageTypeAction(type) || - IsCommandTypeAction(type) || - IsEventTypeAction(type) || - IsInSystemConventionList(type)); + type => + { + if (IsInSystemConventionList(type)) + { + return true; + } + if (IsFromParticularAssembly(type)) + { + return false; + } + return IsMessageTypeAction(type) || + IsCommandTypeAction(type) || + IsEventTypeAction(type); + }); } catch (Exception ex) { @@ -73,7 +98,14 @@ public static bool IsCommandType(Type t) { try { - return CommandsConventionCache.ApplyConvention(t, type => IsCommandTypeAction(type)); + return CommandsConventionCache.ApplyConvention(t, type => + { + if (IsFromParticularAssembly(type)) + { + return false; + } + return IsCommandTypeAction(type); + }); } catch (Exception ex) { @@ -96,7 +128,14 @@ public static bool IsExpressMessageType(Type t) { try { - return ExpressConventionCache.ApplyConvention(t, type => IsExpressMessageAction(type)); + return ExpressConventionCache.ApplyConvention(t, type => + { + if (IsFromParticularAssembly(type)) + { + return false; + } + return IsExpressMessageAction(type); + }); } catch (Exception ex) { @@ -151,7 +190,14 @@ public static bool IsEventType(Type t) { try { - return EventsConventionCache.ApplyConvention(t, type => IsEventTypeAction(type)); + return EventsConventionCache.ApplyConvention(t, type => + { + if (IsFromParticularAssembly(type)) + { + return false; + } + return IsEventTypeAction(type); + }); } catch (Exception ex) { diff --git a/src/NServiceBus/NServiceBus.csproj b/src/NServiceBus/NServiceBus.csproj index 9bc5821f71b..e527908b88d 100644 --- a/src/NServiceBus/NServiceBus.csproj +++ b/src/NServiceBus/NServiceBus.csproj @@ -55,6 +55,9 @@ + + InternalsVisibleTo.cs +