Просмотр исходного кода

extends CodeException as generic for use Enumerations, publish fnd.core package

Dalibor Votruba 2 лет назад
Родитель
Сommit
4cfcb0df69

+ 15 - 0
qdr.fnd.core/Attributes/ErrorMessageAttribute.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace Quadarax.Foundation.Core.Attributes
+{
+    [AttributeUsage(validOn:AttributeTargets.Field)]
+    public class ErrorMessageAttribute : Attribute
+    {
+        public string ErrorMessage { get; private set; }
+
+        public ErrorMessageAttribute(string errorMessage)
+        {
+            ErrorMessage = errorMessage;
+        }
+    }
+}

+ 90 - 0
qdr.fnd.core/Exceptions/CodeException.cs

@@ -1,10 +1,18 @@
 using System;
+using System.Collections.Generic;
+using System.Linq;
+using Quadarax.Foundation.Core.Attributes;
+using Quadarax.Foundation.Core.Value.Extensions;
 
 namespace Quadarax.Foundation.Core.Exceptions
 {
+    /// <summary>
+    /// Provides a base class for exceptions that include a code.
+    /// </summary>
     [Serializable]
     public class CodeException : Exception
     {
+        public int Code => this.GetCode();
         public CodeException(int code, string message, Exception innerException) : base(message, innerException)
         {
             this.SetCode(code);
@@ -14,5 +22,87 @@ namespace Quadarax.Foundation.Core.Exceptions
         {
             this.SetCode(code);
         }
+       
+        public CodeException(int code, string message, params object[] messageArguments) : base(string.Format(message, messageArguments))
+        {
+            this.SetCode(code);
+        }
+        public CodeException(int code, string message, Exception innerException, params object[] messageArguments) : base(string.Format(message, messageArguments), innerException)
+        {
+            this.SetCode(code);
+        }
+
+    }
+
+    /// <summary>
+    /// Provides a base class for exceptions that include a code in enumeration form.
+    /// Exception message is resolved from the <see cref="ErrorMessageAttribute"/> of the enumeration.
+    /// </summary>
+    /// <typeparam name="TCodeEnum">Enumeration that defines error codes end its message defined by <see cref="ErrorMessageAttribute"/>.</typeparam>
+    public class CodeException<TCodeEnum> : CodeException where TCodeEnum : struct, Enum
+    {
+
+        public new TCodeEnum Code => (TCodeEnum)Enum.ToObject(typeof(TCodeEnum), this.GetCode());
+
+        /// <summary>
+        /// Static cache for error messages.
+        /// </summary>
+        private static readonly IDictionary<int, string> _messageCache = new Dictionary<int, string>();
+
+        public CodeException(TCodeEnum code, Exception innerException) : base(Convert.ToInt32(code),
+            ResolveMessage(code), innerException)
+        {
+        }
+
+        public CodeException(TCodeEnum code) : base(Convert.ToInt32(code), ResolveMessage(code))
+        {
+        }
+
+        public CodeException(TCodeEnum code, params object[] messageArguments) : base(
+            Convert.ToInt32(code), ResolveMessage(code, messageArguments))
+        {
+        }
+
+        public CodeException(TCodeEnum code, Exception innerException, params object[] messageArguments)
+            : base(Convert.ToInt32(code),ResolveMessage(code,messageArguments), innerException)
+        {
+        }
+
+        private static string ResolveMessage(TCodeEnum code, params object[] messageArguments)
+        {
+            var codeValue = Convert.ToInt32(code);
+            // check if cache is initialized
+            if (_messageCache.Count == 0)
+            {
+                // initialize cache
+                var fields = typeof(TCodeEnum).GetFields();
+                var names = Enum.GetNames(typeof(TCodeEnum)).ToArray();
+                var values = Enum.GetValues(typeof(TCodeEnum));
+                // iterate through all fields of the enumeration
+                foreach (var field in fields)
+                {
+                    var attr = field.GetCustomAttributes(typeof(ErrorMessageAttribute), false);
+                    var index = Array.IndexOf(names, field.Name);
+                    if (index<0) continue;
+                    var fieldVal = (int) (values.GetValue(index) ?? -1);
+                    // if value has attribute ErrorMessageAttribute, add it to the cache
+                    if (attr.Length == 1)
+                    {
+                        var message = ((ErrorMessageAttribute)attr[0]).ErrorMessage;
+                        _messageCache.Add(fieldVal, message);
+                    }
+                    else
+                    {
+                        // message not found, log warning and add default message to the cache
+                        System.Diagnostics.Debug.WriteLine($"Error message in enumeration '{typeof(TCodeEnum).Name}' not found for code '{codeValue}'", "WARN");
+                        _messageCache.Add(fieldVal, $"Error message code: {code} [{fieldVal}]");
+                    }
+                }
+            }
+            // return message from cache
+            return string.Format(_messageCache[codeValue], messageArguments);
+        }
+
     }
+     
 }

+ 8 - 8
qdr.fnd.core/qdr.fnd.core.csproj

@@ -12,15 +12,15 @@
     <Company>Quadarax</Company>
     <Product>Quadarax.Foundation</Product>
     <Description>Core library with general pattern implementations and patterns</Description>
-    <Copyright>Copyright © 2023 Quadarax</Copyright>
+    <Copyright>Copyright © 2023,2024 Quadarax</Copyright>
     <PackageIcon>quadarax_dll.png</PackageIcon>
     <PackageTags>QDR;FND;CORE</PackageTags>
-    <AssemblyVersion>0.0.3.0</AssemblyVersion>
-    <FileVersion>0.0.3.0</FileVersion>
-    <Version>0.0.3.0-alpha</Version>
-    <PackageReleaseNotes>Date:30.11.2023
-      - add interface Value/Generators/IIdGenerator to generate unique id
-      - add class Value/Generators/TinyHash to generate string-like balanced (timebased) unique id defined by length and charset
+    <AssemblyVersion>0.0.4.0</AssemblyVersion>
+    <FileVersion>0.0.4.0</FileVersion>
+    <Version>0.0.4.0-alpha</Version>
+    <PackageReleaseNotes>Date:11.3.2024
+      - add constructor to Exceptions/CodeException to support parameter message
+      - add generic class Exceptions/CodeException to work with enumeration codes and messages
       - update dependencies packages (System.IO.Abstractions)
     </PackageReleaseNotes>
     <PackageReadmeFile>releasenotes.md</PackageReadmeFile>
@@ -47,7 +47,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.IO.Abstractions" Version="19.2.87" />
+    <PackageReference Include="System.IO.Abstractions" Version="20.0.28" />
   </ItemGroup>
 
   <ItemGroup>

+ 6 - 0
qdr.fnd.core/releasenotes.md

@@ -1,6 +1,12 @@
 # Quadarax.Foundation.Core * Release notes
 Ordered by version descending
 
+## 0.0.4.0
+Date:__11.3.2024__
+- add constructor to Exceptions/CodeException to support parameter message
+- add generic class Exceptions/CodeException to work with enumeration codes and messages
+- update dependencies packages (System.IO.Abstractions)
+---
 ## 0.0.3.0
 Date:__30.11.2023__
 - add interface Value/Generators/IIdGenerator to generate unique id