转自:http://hi.baidu.com/xyz136299110/item/a32be4269e9d0c55c38d59e6
相信大家看过相当多的IOC依赖注入的例子。
但大家在没有明白原理的情况下,都或多或少有些疑问或者弄不明白程序逻辑。
其实说白了,所以的起点都依赖于XML文件。
下面给出一个非常简单的实例,(例子是说对数字,1-100,偶数的三项验证)
我们经常有有其中的一项或多项验证。那么我们该如何处理呢?抑或我们加入新的验证的时候如何才能最小的修改代码及程序逻辑呢?
怎么样才能使新的验证逻辑(A编写验证逻辑,B调用验证方法,那么当新的验证逻辑存在时,如何才能最小耦合呢??)
这就用到反射依赖注入了滴。
OK,贴上实例。
一、验证逻辑
1.数字验证
public class NumCheck:ICheck
{
public bool IsCheckRight(int Number)
{
Regex regex = new Regex("^[0-9]*$");
return regex.IsMatch(Number.ToString().Trim());
}
}
2.偶数验证
public class OSCheck:ICheck
{
public bool IsCheckRight(int Number)
{
bool flag=false;
int number = 0;
if (int.TryParse(Number.ToString(), out number))
{
if (number % 2 == 0)
{
flag = true;
}
}
return flag;
}}
3.范围验证
public class RangeCheck:ICheck
{
public bool IsCheckRight(int Number)
{
bool flag = false;
int number = 0;
if (int.TryParse(Number.ToString(), out number))
{
if (number >= 1 && number <= 100)
{
flag = true;
}
}
return flag;
} }
二。接口定义
public interface ICheck
{
/// 是否验证成功
bool IsCheckRight(int Number);
}
三.工厂反射
public static class AFactory
{
private static Hashtable bllList = null;
private static Object lockobj = new Object();
public static ICheck GetBLLInterface(string assemblyName, string bllClassName)
{
ICheck ret = null;
try
{
if (bllList == null)
{
bllList = new Hashtable();
}
if (bllList[assemblyName] == null)
{
lock (lockobj)
{
Assembly assembly = Assembly.Load(assemblyName);
ret = (ICheck)assembly.CreateInstance(bllClassName);
bllList.Add(assemblyName, assembly);
}
}
else
{
Assembly assembly = (Assembly)bllList[assemblyName];
ret = (ICheck)assembly.CreateInstance(bllClassName);
}
}
catch (Exception ex)
{
}
return ret;
}
}
四.注入点(XML文件此处)
<?xml version="1.0" encoding="utf-8" ?>
<DataKeys>
<add key="NumCheck" value="Com.Area.DAL.NumCheck"></add>
<add key="OSCheck" value="Com.Area.DAL.OSCheck"></add>
<add key="RangeCheck" value="Com.Area.DAL.RangeCheck"></add>
</DataKeys>
五.统一的验证逻辑类
public class BaseCheck
{
private static readonly string Path = "Com.Area.DAL";
public static ICheck GetIcheck(string CheckKey)
{
string ClassName = string.Empty;
DataSet ds = new DataSet();
if (!string.IsNullOrEmpty(CheckKey))
{
ds.ReadXml("../../Check.xml");
ClassName = ds.Tables[0].Rows[Convert.ToInt32(CheckKey)-1][1].ToString().Trim();
return AFactory.GetBLLInterface(Path, ClassName) as ICheck;
}
else
return null;
}
public static bool Check(int Number,ref string Msg)
{
bool flag = true;
string ClassName = string.Empty;
DataSet ds = new DataSet();
ds.ReadXml("../../Check.xml");
for (var i = 0; i < ds.Tables[0].Rows.Count; i++)
{
ClassName = ds.Tables[0].Rows[i][1].ToString().Trim();
ICheck check = AFactory.GetBLLInterface(Path, ClassName) as ICheck;
if (!check.IsCheckRight(Number))
{
flag = false;
Msg = "验证失败";
break;
}
}
return flag;
}
}
六.操作界面
代码如下:
private void button1_Click(object sender, EventArgs e)
{
btnClick(button1);
}
private void button4_Click(object sender, EventArgs e)
{
if (this.textBox1.Text == "" || this.textBox1.Text.Length <= 0)
{
MessageBox.Show("ERROR");
}
else
{
string Mesg = string.Empty;
if (!BaseCheck.Check(Convert.ToInt32(this.textBox1.Text), ref Mesg))
{
MessageBox.Show(Mesg);
}
else { MessageBox.Show("Right"); }
}
}
private void button3_Click(object sender, EventArgs e)
{
btnClick(button3);
}
private void button2_Click(object sender, EventArgs e)
{
btnClick(button2);
}
private void btnClick(Button btn)
{
if (this.textBox1.Text == "" || this.textBox1.Text.Length <= 0)
{
MessageBox.Show("ERROR");
}
else
{
string Tag = btn.Tag.ToString().Trim();
ICheck check = BaseCheck.GetIcheck(Tag);
if (check.IsCheckRight(Convert.ToInt32(this.textBox1.Text)))
{
MessageBox.Show("验证成功");
}
else { MessageBox.Show("Error!"); }
}
}