应用场景:随便给一些数字,要求对这些数字进行一项基本的数据运算(例子中只实现了加法/乘法)
先添加对Microsoft.Practices.Unity.dll的引用
准备测试用的接口和类:
///
/// 接口
///
public interface Icalculate
{
int Calculate(params int[] a);
double Calculate(params double[] a);
string GetOperationName();
}
///
/// 加法运算
///
public class Addtive : Icalculate
{
///
/// 注意:至少要有一个构造函数,否则用配置文件方式Resolve
///
public Addtive() { }
public int Calculate(params int[] a)
{
int Result = 0;
foreach (int x in a)
{
Result += x;
}
return Result;
}
public double Calculate(params double[] a)
{
double Result = 0.0;
foreach (double x in a)
{
Result += x;
}
return Result;
}
public string GetOperationName()
{
return "加法";
}
}
///
/// 乘法运算
///
public class Multiplication : Icalculate
{
public Multiplication() { }
public int Calculate(params int[] a)
{
int Result = 1;
foreach (int x in a)
{
Result *= x;
}
return Result;
}
public double Calculate(params double[] a)
{
double Result = 1.0;
foreach (double x in a)
{
Result *= x;
}
return Result;
}
public string GetOperationName()
{
return "乘法";
}
}
///
/// (四则)运算管理器
///
public class CalcManager
{
private Icalculate _calc;
public CalcManager(Icalculate IC)
{
_calc = IC;
}
//[InjectionMethod]
//public void SetCalculate(Icalculate IC) {
// _calc = IC;
//}
public void Compute(params int[] a)
{
string _paramName = "";
foreach (int x in a)
{
_paramName += x.ToString() + ",";
}
_paramName = _paramName.Trim(',');
Console.WriteLine("{0} {1}计算结果:{2}", _paramName, _calc.GetOperationName(), _calc.Calculate(a));
}
public void Compute(params double[] a)
{
string _paramName = "";
foreach (double x in a)
{
_paramName += x.ToString() + ",";
}
_paramName = _paramName.Trim(',');
Console.WriteLine("{0} {1}计算结果:{2}", _paramName, _calc.GetOperationName(), _calc.Calculate(a));
}
}
为了对比,我们先用传统方式来调用试下:
static void Main(string[] args)
{
#region 不用依赖注入的传统方式
CalcManager CM = new CalcManager(new Addtive());
CM.Compute(1, 2, 3, 4, 5);//计算1,2,3,4,5的和
//CM = new CalcManager(new Multiplication());
//CM.Compute(1, 2, 3, 4, 5);//计算1,2,3,4,5的乘积
#endregion
Console.ReadLine();
}
虽然简单易懂,但细想一下可扩展性并不高,如果以后又增加了除法,平方,减法...等一系列算法,不是每次都要这一段代码吗?原因就是接口,算法实体类,调用程序之间的耦合性太高接下来,我们用Unity换一种写法:
using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
static void Main(string[] args)
{
#region 使用依赖注入(硬编码方式)
IUnityContainer container = new UnityContainer();
container.RegisterType
.RegisterType
CalcManager CM = container.Resolve
CM.Compute(1.1, 2.9, 3.1, 4, 5);
//container.RegisterType
//CM = container.Resolve
//CM.Compute(1, 2, 3, 4, 5);
#endregion
Console.ReadLine();
}
单从代码上看,只不过换了种写法和思路,但仍然属于“硬编码”的方式,如果要增加其它算法或换成其它算法,一样还是要改这段代码.(貌似纯属瞎折腾?呵呵)下面切入正题,Unity除了这种硬编码方式,还允许把注入规则/映射写到配置文件里先修改App.Config,内容大致如下:
同时再新建一个config目录,把DI.config文件放在该目录下,内容:
<!--结实验,下面这一行加不加程序都能运行,只要确保CalcManager中有一个参数为Icalculate的构架函数或(注入)设置方法就行[参看CalcManager中注释掉的部分],Unity在这一点上确实比较“智能”-->
调用代码再换一种写法:
static void Main(string[] args)
{
#region 使用依赖注入(配置文件方式)
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
CalcManager CM = container.Resolve
CM.Compute(1, 2, 3, 4, 5);
#endregion
Console.ReadLine();
}
这回仔细看下,代码中已经完全找不到Addtive,Multiplication等这些具体的类名了,整个程序完全依赖于配置文件中的相关节点(其实OO的角度来讲,是基于接口Icalculate的编程以及不同对象的组合让这一切成为可能)。如果我们要把乘法运算换成加法运算,太容易了,把DI.config中的
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1806/viewspace-2801275/ ,如需转载,请注明出处,否则将追究法律责任。