Переглянути джерело

Merge branch 'routing_exception' fixes #20

Conflicts:
	src/Abc.Zebus.Tests/Abc.Zebus.Tests.csproj
Kevin Lovato 10 роки тому
батько
коміт
5e61b96081

+ 1 - 1
src/Abc.Zebus.Tests/Abc.Zebus.Tests.csproj

@@ -81,6 +81,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="BindingKeyTests.cs" />
+    <Compile Include="CommandResultTests.cs" />
     <Compile Include="Comparison\ComparisonExtensionsTests.cs" />
     <Compile Include="Core\BusFactoryTests.cs" />
     <Compile Include="Core\BusInMemoryTests.cs" />
@@ -125,7 +126,6 @@
     <Compile Include="MessageContextTests.cs" />
     <Compile Include="Messages\FakeCommandWithTimestamp.cs" />
     <Compile Include="Messages\FakeInfrastructureTransientCommand.cs" />
-    <Compile Include="Routing\BindingKeyTests.cs" />
     <Compile Include="Scan\StaticAsyncMessageHandlerInvokerLoaderTests.cs" />
     <Compile Include="Scan\SyncMessageHandlerInvokerLoaderTests.cs" />
     <Compile Include="Dispatch\DispatchMessages\SyncCommandHandlerWithQueueName1.cs" />

+ 11 - 0
src/Abc.Zebus.Tests/BindingKeyTests.cs

@@ -55,6 +55,17 @@ namespace Abc.Zebus.Tests
             Measure.Execution(1000000, () => BindingKey.Create(message));
         }
 
+        [Test]
+        public void should_send_routing_key_exception()
+        {
+            var msg = new FakeRoutableCommand(0, null);
+
+            var exception = Assert.Throws<InvalidOperationException>(() => BindingKey.Create(msg));
+            exception.Message.ShouldContain(typeof(FakeRoutableCommand).Name);
+            exception.Message.ShouldContain("Name");
+            exception.Message.ShouldContain("can not be null");
+        }
+
         [Routable]
         public class FakeRoutableCommandWithProperties : ICommand
         {

+ 50 - 0
src/Abc.Zebus.Tests/CommandResultTests.cs

@@ -0,0 +1,50 @@
+using Abc.Zebus.Testing.Extensions;
+using NUnit.Framework;
+
+namespace Abc.Zebus.Tests
+{
+    [TestFixture]
+    public class CommandResultTests
+    {
+        private enum FakeEnumErrorCode
+        {
+            [System.ComponentModel.Description("This is a fake error message")]
+            SomeErrorValue = 1,
+            [System.ComponentModel.Description("This is a fake {0} error message")]
+            SomeErrorValueWithFormat = 2,
+            NoDescriptionErrorValue = 3
+        }
+
+        [Test]
+        public void should_retrieve_empty_error_message_from_command_result_with_no_error()
+        {
+            var cmdResult = new CommandResult(0, null);
+
+            cmdResult.GetErrorMessageFromEnum<FakeEnumErrorCode>().ShouldBeEmpty();
+        }
+
+        [Test]
+        public void should_retrieve_error_message_from_command_result_with_enum_description()
+        {
+            var cmdResult = new CommandResult((int)FakeEnumErrorCode.SomeErrorValue, null);
+
+            cmdResult.GetErrorMessageFromEnum<FakeEnumErrorCode>().ShouldEqual("This is a fake error message");
+        }
+
+        [Test]
+        public void should_retrieve_error_message_from_command_result_with_enum_description_and_format()
+        {
+            var cmdResult = new CommandResult((int)FakeEnumErrorCode.SomeErrorValueWithFormat, null);
+
+            cmdResult.GetErrorMessageFromEnum<FakeEnumErrorCode>("formated").ShouldEqual("This is a fake formated error message");
+        }
+
+        [Test]
+        public void should_retrieve_empty_error_message_from_command_result_with_enum_no_description()
+        {
+            var cmdResult = new CommandResult((int)FakeEnumErrorCode.NoDescriptionErrorValue, null);
+
+            cmdResult.GetErrorMessageFromEnum<FakeEnumErrorCode>().ShouldBeEmpty();
+        }
+    }
+}

+ 36 - 0
src/Abc.Zebus.Tests/DomainExceptionTests.cs

@@ -72,5 +72,41 @@ namespace Abc.Zebus.Tests
             ex.ErrorCode.ShouldEqual(3712);
             ex.Message.ShouldEqual(string.Empty);
         }
+
+        private enum FakeEnumErrorCode
+        {
+            [System.ComponentModel.Description("This is a fake error message")]
+            SomeErrorValue = 1,
+            [System.ComponentModel.Description("This is a fake error message with a formatted parameter {0}")]
+            AnotherErrorValue = 2,
+            YetAnotherErrorValue = 3
+        }
+
+        [Test]
+        public void should_obtain_error_message_via_enum_attribute()
+        {
+            var ex = new DomainException(FakeEnumErrorCode.SomeErrorValue);
+
+            ex.ErrorCode.ShouldEqual((int)FakeEnumErrorCode.SomeErrorValue);
+            ex.Message.ShouldEqual("This is a fake error message");
+        }
+
+        [Test]
+        public void should_obtain_error_message_via_enum_attribute_with_formatted_parameter()
+        {
+            var ex = new DomainException(FakeEnumErrorCode.AnotherErrorValue, "formatted param");
+
+            ex.ErrorCode.ShouldEqual((int)FakeEnumErrorCode.AnotherErrorValue);
+            ex.Message.ShouldEqual("This is a fake error message with a formatted parameter formatted param");
+        }
+
+        [Test]
+        public void should_not_fail_if_enum_attribute_is_not_defined()
+        {
+            var ex = new DomainException(FakeEnumErrorCode.YetAnotherErrorValue);
+
+            ex.ErrorCode.ShouldEqual((int)FakeEnumErrorCode.YetAnotherErrorValue);
+            ex.Message.ShouldEqual(string.Empty);
+        }
     }
 }

+ 0 - 24
src/Abc.Zebus.Tests/Routing/BindingKeyTests.cs

@@ -1,24 +0,0 @@
-using System;
-using Abc.Zebus.Routing;
-using Abc.Zebus.Testing;
-using Abc.Zebus.Testing.Extensions;
-using Abc.Zebus.Tests.Messages;
-using NUnit.Framework;
-
-namespace Abc.Zebus.Tests.Routing
-{
-    [TestFixture]
-    public class BindingKeyTests
-    {
-        [Test]
-        public void should_send_routing_key_exception()
-        {
-            var msg = new FakeRoutableCommand(0, null);
-
-            var exception = Assert.Throws<InvalidOperationException>(() => BindingKey.Create(msg));
-            exception.Message.ShouldContain(typeof(FakeRoutableCommand).Name);
-            exception.Message.ShouldContain("Name");
-            exception.Message.ShouldContain("can not be null");
-        }
-    }
-}

+ 1 - 0
src/Abc.Zebus/Abc.Zebus.csproj

@@ -219,6 +219,7 @@
     <Compile Include="Util\DisposableAction.cs" />
     <Compile Include="Util\Extensions\ExtendDictionary.cs" />
     <Compile Include="Util\Extensions\ExtendICollection.cs" />
+    <Compile Include="Util\Extensions\ExtendEnum.cs" />
     <Compile Include="Util\Extensions\ExtendIEnumerable.cs" />
     <Compile Include="Util\Extensions\ExtendString.cs" />
     <Compile Include="Util\Extensions\ExtendType.cs" />

+ 15 - 2
src/Abc.Zebus/CommandResult.cs

@@ -1,4 +1,7 @@
-namespace Abc.Zebus
+using Abc.Zebus.Util.Extensions;
+using System;
+
+namespace Abc.Zebus
 {
     public class CommandResult
     {
@@ -15,5 +18,15 @@
         {
             get { return ErrorCode == 0; }
         }
+
+        public string GetErrorMessageFromEnum<T>(params object[] formatValues) where T : struct, IConvertible, IFormattable, IComparable
+        {
+            if (IsSuccess)
+                return string.Empty;
+
+            var value = (T)Enum.Parse(typeof(T), ErrorCode.ToString());
+
+            return string.Format(((Enum)(object)value).GetAttributeDescription(), formatValues);
+        }
     }
-}
+}

+ 9 - 3
src/Abc.Zebus/DomainException.cs

@@ -3,6 +3,7 @@ using System.ComponentModel;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Reflection;
+using Abc.Zebus.Util.Extensions;
 
 namespace Abc.Zebus
 {
@@ -16,10 +17,15 @@ namespace Abc.Zebus
             ErrorCode = errorCode;
         }
 
+        public DomainException(Enum enumVal, params object[] values)
+            : this (Convert.ToInt32(enumVal), enumVal.GetAttributeDescription(), values)
+        {
+        }
+
         public DomainException(Expression<Func<int>> errorCodeExpression, params object[] values)
-            : base(string.Format(ReadDescriptionFromAttribute(errorCodeExpression), values))
+            : this (errorCodeExpression.Compile()(), ReadDescriptionFromAttribute(errorCodeExpression), values)
+   
         {
-            ErrorCode = errorCodeExpression.Compile()();
         }
 
         static string ReadDescriptionFromAttribute(Expression<Func<int>> errorCodeExpression)
@@ -33,4 +39,4 @@ namespace Abc.Zebus
             return attr != null ? attr.Description : string.Empty;
         }
     }
-}
+}

+ 23 - 0
src/Abc.Zebus/Util/Extensions/ExtendEnum.cs

@@ -0,0 +1,23 @@
+using System;
+using System.ComponentModel;
+
+namespace Abc.Zebus.Util.Extensions
+{
+    internal static class ExtendEnum
+    {
+        public static string GetAttributeDescription(this Enum enumValue)
+        {
+            var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();
+
+            return attribute == null ? String.Empty : attribute.Description;
+        }
+
+        private static T GetAttributeOfType<T>(this Enum enumVal) where T : Attribute
+        {
+            var enumType = enumVal.GetType();
+            var memberInfo = enumType.GetMember(enumVal.ToString());
+
+            return memberInfo[0].GetAttribute<T>(false);
+        }
+    }
+}