.NET:可扩展的单据编号生成器 + 简单的解释器
2013-05-12 09:38
204 查看
背景
在企业应用中单据编号的自定义是一个很常见的需求,能不能抽象一个通用的框架呢?之前写个一篇自定义密码强度的博文,感觉他们两个思路应该很相似。就让我们试试吧。思路
这里的难点在于实现"解释器",比如将"前缀_<日期:yyyy_MM_dd>"解释为“工号生成器”,而且“解释器”的“规则”允许动态增加。
实现
代码下载
类图
核心代码
CodeRuleGenerator.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; namespace EntityCodeRuleDemo { public sealed class CodeRuleGenerator : ICodeRuleGenerator { private readonly IEnumerable<ICodeRuleProvider> _providers = new List<ICodeRuleProvider>(); internal CodeRuleGenerator(IEnumerable<ICodeRuleProvider> providers) { _providers = providers; } public string Generate(object entity) { var sb = new StringBuilder(); foreach (var provider in _providers) { sb.Append(provider.Generate(entity)); } return sb.ToString(); } } }
CodeRuleInterpreter.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; using EntityCodeRuleDemo.RuleProviders; namespace EntityCodeRuleDemo { public static class CodeRuleInterpreter { private static Dictionary<Regex, Func<string, ICodeRuleProvider>> _providerFactorys = new Dictionary<Regex, Func<string, ICodeRuleProvider>>(); static CodeRuleInterpreter() { SetProviderFactory(new Regex("^[^<].*?[^>]?$"), LiteralRuleProvider.LiteralRuleProviderFactory); SetProviderFactory(new Regex("^<日期(:(?<格式>.*?))?>$"), DateRuleProvider.DateRuleProviderFactory); SetProviderFactory(new Regex("^<属性(:(?<名称>.*?))?>$"), PropertyRuleProvider.PropertyRuleProviderFactory); } public static void SetProviderFactory(Regex regex, Func<string, ICodeRuleProvider> providerFactory) { _providerFactorys[regex] = providerFactory; } public static ICodeRuleGenerator Interpret(string codeRule) { var providers = GetProviders(codeRule); return new CodeRuleGenerator(providers); } private static IEnumerable<ICodeRuleProvider> GetProviders(string codeRule) { var literals = codeRule.Replace("<", "$<").Replace(">", ">$").Split('$'); return literals .Where(x => !string.IsNullOrEmpty(x)) .Select(GetProvider) .ToList(); } private static ICodeRuleProvider GetProvider(string literal) { var providerFactory = _providerFactorys .FirstOrDefault(x => x.Key.IsMatch(literal)) .Value; if (providerFactory == null) { throw new FormatException("格式化错误"); } return providerFactory(literal); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EntityCodeRuleDemo { class Program { static void Main(string[] args) { var employeeCode = CodeRuleInterpreter .Interpret("前缀_<日期:yyyy_MM_dd>_<属性:NamePinYin>") .Generate(new Employee { NamePinYin = "DUANGW" }); Console.WriteLine(employeeCode); } } class Employee { public string NamePinYin { get; set; } public string EmployeeCode { get; set; } } }
运行效果
备注
按照这种思路,基本上能满足企业应用的多数编码规则要求。在真实的项目中,这些规则是要持久化到数据库的,这样就可以做到运行时动态的修改规则了。相关文章推荐
- .NET:可扩展的单据编号生成器 之 基于缓冲区的顺序号
- .Net可扩展的单据编号生成器-SNF.CodeRule--SNF快速开发平台3.2
- .NET:可扩展的单据编号生成器 之 基于缓冲区的顺序号
- .NET:可扩展的单据编号生成器 之 顺序号(防止重复)
- 幸福框架:如何扩展编号生成器
- 不再使用自动编号了。自己写了一个Id生成器,超级简单
- 幸福框架:可扩展的、动态的、万能的 编号生成器
- JS简单编号生成器实现方法(附demo源码下载)
- 幸福框架:如何扩展编号生成器
- 幸福框架:可扩展的、动态的、万能的 编号生成器
- .net 简单易懂的扩展方法教程
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
- 幸福框架:可扩展的、动态的、万能的 编号生成器
- 用.net简单写个E-mail发送功能及扩展功能
- JS简单编号生成器实现方法(附demo源码下载)
- 不再使用自动编号了。自己写了一个Id生成器,超级简单
- 为Disruptor 写的一个简单实用的.Net扩展
- .Net(C#)最简单的邮件发送案例
- .NET Framewok 3.5 中 JSON 序列化和反序列化的简单实现
- .NET中对类的扩展