惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Project Zero
Project Zero
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
Know Your Adversary
Know Your Adversary
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Jina AI
Jina AI
AI
AI
美团技术团队
人人都是产品经理
人人都是产品经理
S
Secure Thoughts
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
宝玉的分享
宝玉的分享
Security Latest
Security Latest
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
大猫的无限游戏
大猫的无限游戏
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
罗磊的独立博客
Recent Announcements
Recent Announcements
H
Hacker News: Front Page
博客园 - 【当耐特】
K
Kaspersky official blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
F
Full Disclosure
Google DeepMind News
Google DeepMind News
V
V2EX
博客园 - 聂微东
量子位
云风的 BLOG
云风的 BLOG
C
Check Point Blog
J
Java Code Geeks
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
W
WeLiveSecurity
Engineering at Meta
Engineering at Meta
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
L
LINUX DO - 热门话题
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
The GitHub Blog
The GitHub Blog

博客园 - shenpeng

C#中的具名参数和可选参数 C#中使用ExcelDataReader读取Excel文件 使用OleDbCommandBuilder时出现“Insert into 语句的语法错误”的解决方法(转) 在eclipse中使用中文JAVA api文档 .NET、ASP.NET控件及源码大汇总 60多个精品源码站 ASP.net常用代码(常用技巧备忘) C#程序转为VB.NET程序的一个小问题 Any和Some和ALL 的使用,以及交操作差操作的嵌套查询(Oracle) (转) CEIL和FLOOR函数查询(Oracle,MSSQL) (转) 字符串分割自定义函数(SQL) (转) ORACLE中巧用一条SQL 实现其它进制到十进制转换(转) 数据库优化设计方案(转) 数字格式化(转) 将DataSet导出成XLS、XML、HTML、CSV、TSV等格式 纵表变横表经典中的经典 Web页面的数据导出excel时的格式问题(转) Access中使用SQL语句应掌握的几点技巧(转) 在SQL Server中修改sa的密码
浅谈反射与特性在接口系统中的应用(编码表转化) (转)
shenpeng · 2008-03-17 · via 博客园 - shenpeng

本文引用:http://www.cnblogs.com/rijing2004/archive/2007/12/20/attribute_applicance.html

问题描述:

业务系统AB需要共享数据,以达到数据利用最大化,减少工作人员的录入数据的工作量。说明一下,业务系统AB各自使用不同的编码表,简单的说,在业务系统A中,性别是使用0102代表男和女,而在业务系统B中,性别则采用了mw表示男和女。现在,这两个系统要共享性别这个数据项,所以我们需要做的必不可少的工作就是:编码表的转化。这个问题有很高的普遍性,基本上只要是业务系统之间共享数据,那么这一步是必不可少的。今天,我就对此问题谈一谈我的解决之道,供大家探讨。

解决思路:

1)  我们最容易想到的办法就是,编写一个方法,针对输入的编码进行匹配转化,如一下代码所示:

public static string SexCodeToJS(string code)
    
{
            
string result = string.Empty;
            
switch(code.Trim())
            
{
                
case "01":
                    result 
= "m";
                    
break;
                
case "02"
                    result 
= "w";
                    
break;
            }

            
return result;
    }

 

然 后,在外部进行调用此方法即可。如果我们的编码表转化数量比较少的话,这一种方法,显然已经可以满足要求了。但假如我们有很多的编码表需要转化,这一种方 法使用起来应该是很吃力的。而且,一旦数据项的编码之间对应关系一旦发生变化,我们就必须要改写程序,然后编译、发布。显然此方法的灵活性还不太好。那么 我们就需要寻找另一种灵活的,可以应对编码对应关系可能会变的方法。

1)  使用数据库或者xml存储编码表之间的对应关系。使用数据库也好,xml也好,都是把问题的可变性单独分离出来,以数据库存储为例,可以设计如下表结构(脚本如下):

create table CodeConvert
(
id 
int identity(1,1primary key,
codeType 
varchar(10), --编码的类型
codeA varchar(10), --业务系统A的编码
codeA_Name varchar(20), --业务系统A的对应编码的描述
codeB varchar(10),--业务系统B的编码
codeB_Name varchar(20--业务系统B的对应编码的描述
)


 

在这个表里存储编码之间的映射关系。现在,如果你需要转化,那么你就需要 查询这个表,就可以得到转化后的编码。而且一旦编码之间的对应关系变了,那么你只需要修改这个表里的数据即可完成修改,相对上一种方法,已经增加抗变性。 再回头看,抗变性是增加了,可是客户程序使用的时候仍然比较麻烦,仍然需要关心,哪个编码需要转化。其实,从职责分配的角度讲,哪个编码需要转化,是在使 用之前就可以确定下来的事情,所以我们可不可以让编码自动转化呢?如果可以的话,那么客户程序就不再需要关心哪个编码需要转化的事情啦,毕竟这是一件烦人 的事情。现在,我们整理一下思路,假设有一个负责转化的方法,如下:

public static string ConvertCode(string codeType,string systemACode)
{}

 
那么,目前如果有一个实体类Person需要转化编码的时候,需要调用:

Person p = GetPerson();
p.SexCode 
= ConvertCode("CodeType",p.SexCode);
p.MarriageStatusCode 
= ConvertCode("CodeType",p.MarriageStatusCode);


  可以看出,我们需要知道哪一个属性的编码需要转化。那么,我们希望编码可以自动转化,使用编码转化时,不再关心哪一个属性的编码需要转化,代码如下:

Person p = GetPerson();

= ConvertObjectCode(p); //一次性把所有需要转化的编码全部转化。

这样的代码看起来会比较舒服,客户代码只需要关心何时转化编码,而不关心编码如何转化,这就是职责的分离。

我们应该怎样编写ConvertObjectCode(object convert_obj)方法呢?下面就重点介绍使用反射和特性(自定义属性)就可以做到。

为了更好的提高方法的使用性,我们会给ConvertObjectCode方法添加一个参数,用于指示,编码转化的方向,即:是从业务系统AB还是BA。添加这个参数这个方法就可以做到双向转化啦。

让我们继续探讨ConvertObjectCode方法的功能吧。在这里,这个方法需要做的事情是:转化类的属性编码,但要转化的结果则归属于类的属性,因为每个属性转化后的结果是不一样的,而要转化为什么,类的属性是知道的。所以,在这里我们需要再次细化职责,ConvertObjectCode方法只负责转化,而转化为什么则由类的属性承担。看到这里,可能你已经知道如何做啦,那就看一下代码吧。

首先,需要编写一个特性,用于标注哪一个类的属性需要转化,做何种转化。代码如下:

[AttributeUsage(AttributeTargets.Property,AllowMultiple = false)]
    
public class CodeConvertAttribute:Attribute
    
{
        
public CodeConvertAttribute(string codeType)
        
{
            
this.m_codeType = codeType;
        }

        
private string m_codeType;
        
public string CodeType //编码的类型
        {
            
get
            
{
                
return this.m_codeType;
            }

            
set
            
{
                
this.m_codeType = value;
            }

        }

    }


  其次,在需要做编码转化类的属性上加特性。代码如下:

[CodeConvert(CodeType.Sex)]
        
public string Sex
        
{
            
get
            
{
                
return m_Sex;
            }

            
set
            
{
                
this.m_Sex = value;
            }

        }


  最后,做转化的动作,如下:

/// <summary>
        
/// 自动转化实体类的各个属性的编码(系统A与系统B)
        
/// </summary>
        
/// <param name="convertObj">要转化的对象</param>
        
/// <param name="huNanToLocal">true:A的编码转化为B;false:B的编码转化为A</param>
        
/// <returns></returns>

        public static object AutoConvertCode(object convertObj,bool ToLocal)
        
{
            Type type 
= convertObj.GetType();
            PropertyInfo[] props 
= type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            
foreach(PropertyInfo p in props)
            
{
                
object convertObj_value = p.GetValue(convertObj,null);
                
string js_type = string.Empty;
                
object[] customerAttributes = p.GetCustomAttributes(typeof(CodeConvertAttribute),false);
                
if(customerAttributes.Length > 0)
                
{
                    CodeConvertAttribute attr 
= (CodeConvertAttribute)customerAttributes[0];
                    js_type 
= attr.CodeType;
                    
if(ToLocal)
                        p.SetValue(convertObj,ConvertCode(js_type,convertObj_value.ToString()),
null);
                    
else
                        p.SetValue(convertObj, ConvertCode (js_type,convertObj_value.ToString()),
null);
                }

                
            }
    
            
return convertObj;
        }


  现在,你就可以轻松的对任意的对象进行编码转化了,如果某个类的属性需要增加编码转化的工作,那么只需要把特性CodeConvert添加到对应的属性上即可,剩下的事情就不用操心啦。怎么样,现在的你还觉得特性和反射遥不可及嘛?