.NET:可擴展的單據編號生成器 + 簡單的解釋器


背景

在企業應用中單據編號的自定義是一個很常見的需求,能不能抽象一個通用的框架呢?之前寫個一篇自定義密碼強度的博文,感覺他們兩個思路應該很相似。就讓我們試試吧。

思路

這里的難點在於實現"解釋器",比如將"前綴_<日期:yyyy_MM_dd>"解釋為“工號生成器”,而且“解釋器”的“規則”允許動態增加。

 

實現

代碼下載

類圖

核心代碼

CodeRuleGenerator.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 using System.Text.RegularExpressions;
 8 
 9 namespace EntityCodeRuleDemo
10 {
11     public sealed class CodeRuleGenerator : ICodeRuleGenerator
12     {
13         private readonly IEnumerable<ICodeRuleProvider> _providers = new List<ICodeRuleProvider>();
14 
15         internal CodeRuleGenerator(IEnumerable<ICodeRuleProvider> providers)
16         {
17             _providers = providers;
18         }
19 
20         public string Generate(object entity)
21         {
22             var sb = new StringBuilder();
23 
24             foreach (var provider in _providers)
25             {
26                 sb.Append(provider.Generate(entity));
27             }
28 
29             return sb.ToString();
30         }
31     }
32 }

CodeRuleInterpreter.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 using System.Text.RegularExpressions;
 8 
 9 using EntityCodeRuleDemo.RuleProviders;
10 
11 namespace EntityCodeRuleDemo
12 {
13     public static class CodeRuleInterpreter
14     {
15         private static Dictionary<Regex, Func<string, ICodeRuleProvider>> _providerFactorys = new Dictionary<Regex, Func<string, ICodeRuleProvider>>();
16 
17         static CodeRuleInterpreter()
18         {
19             SetProviderFactory(new Regex("^[^<].*?[^>]?$"), LiteralRuleProvider.LiteralRuleProviderFactory);
20             SetProviderFactory(new Regex("^<日期(:(?<格式>.*?))?>$"), DateRuleProvider.DateRuleProviderFactory);
21             SetProviderFactory(new Regex("^<屬性(:(?<名稱>.*?))?>$"), PropertyRuleProvider.PropertyRuleProviderFactory);
22         }
23 
24         public static void SetProviderFactory(Regex regex, Func<string, ICodeRuleProvider> providerFactory)
25         {
26             _providerFactorys[regex] = providerFactory;
27         }
28 
29 
30         public static ICodeRuleGenerator Interpret(string codeRule)
31         {
32             var providers = GetProviders(codeRule);
33 
34             return new CodeRuleGenerator(providers);
35         }
36 
37         private static IEnumerable<ICodeRuleProvider> GetProviders(string codeRule)
38         {
39             var literals = codeRule.Replace("<", "$<").Replace(">", ">$").Split('$');
40 
41             return literals
42                 .Where(x => !string.IsNullOrEmpty(x))
43                 .Select(GetProvider)
44                 .ToList();
45         }
46 
47         private static ICodeRuleProvider GetProvider(string literal)
48         {
49             var providerFactory = _providerFactorys
50                 .FirstOrDefault(x => x.Key.IsMatch(literal))
51                 .Value;
52 
53             if (providerFactory == null)
54             {
55                 throw new FormatException("格式化錯誤");
56             }
57 
58             return providerFactory(literal);
59         }
60     }
61 }

Program.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace EntityCodeRuleDemo
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             var employeeCode = CodeRuleInterpreter
14                 .Interpret("前綴_<日期:yyyy_MM_dd>_<屬性:NamePinYin>")
15                 .Generate(new Employee { NamePinYin = "DUANGW" });
16 
17             Console.WriteLine(employeeCode);
18         }
19     }
20 
21     class Employee
22     {
23         public string NamePinYin { get; set; }
24         public string EmployeeCode { get; set; }
25     }
26 }

運行效果

備注

按照這種思路,基本上能滿足企業應用的多數編碼規則要求。在真實的項目中,這些規則是要持久化到數據庫的,這樣就可以做到運行時動態的修改規則了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM