Spring.net step by step——依赖注入(DI)和控制反转(IOC)
依赖注入(Dependeny Injection)简称DI,DI的作用是减少类与类,组件和组件之间的耦合度。依赖注入包括属性注入、构造函数注入。下面我们以公司员工考勤来谈谈依赖注入的应用场景。
公司员工接口和考勤接口
/// <summary>
/// 员工接口
/// </summary>
public interface IPersonnel
{
DateTime StartWork
{
get;
set;
}
DateTime EndWork
{
get;
set;
}
/// <summary>
/// 出勤
/// </summary>
void Attendance();
}
/// <summary>
/// 考勤接口
/// </summary>
public interface ICheckIn
{
/// <summary>
/// 考勤
/// </summary>
/// <param name="stratwork"></param>
/// <param name="endwork"></param>
void CheckIn(DateTime stratwork,DateTime endwork);
}
场景一:所有的员工考勤方案一样。
/// <summary>
/// 普通员工
/// </summary>
public class GeneralStaf : IPersonnel
{
private DateTime _startWork;
private DateTime _endWork;
private ICheckIn checkin;
public GeneralStaf(DateTime stratwork,DateTime endwork)
{
_startWork = stratwork;
_endWork = endwork;
}
/// <summary>
/// 考勤
/// </summary>
public void Attendance()
{
checkin = new GeneralCheckIn();
checkin.CheckIn(_startWork, _endWork);
}
public DateTime StartWork
{
get
{
return _startWork;
}
set
{
_startWork = value;
}
}
public DateTime EndWork
{
get
{
return _endWork;
}
set
{
_endWork = value;
}
}
}
/// <summary>
/// 通用考勤方案
/// </summary>
public class GeneralCheckIn:ICheckIn
{
public void CheckIn(DateTime stratwork, DateTime endwork)
{
Console.WriteLine("stratwork:" + stratwork);
Console.WriteLine("endwork:" + endwork);
if (stratwork.Hour > 9)
{
Console.WriteLine("you are be late!");
}
if (stratwork.Hour < 18)
{
Console.WriteLine("you are leave early");
}
}
}
客服端代码和执行结果。
static void Main(string[] args)
{
IPersonnel personnel = new GeneralStaf(DateTime.Now,DateTime.Now.AddHours(8));
personnel.Attendance();
Console.ReadLine();
}

从上面代码红色标记可以看出。GeneralStaf类和GeneralCheckIn存在着耦合。当考勤类变化时,我们不得不修改GeneralStaf类,这也违反了类的封闭原则。
使用依赖注入解耦
将GeneralStaf修改为
public class GeneralStaff : IPersonnel
{
private DateTime _startWork;
private DateTime _endWork;
private ICheckIn _checkin;
[Required]
public ICheckIn checkIn
{
get
{
return _checkin;
}
set
{
_checkin = value;
}
}
public GeneralStaff()
{
}
public GeneralStaff(DateTime stratwork, DateTime endwork)
{
_startWork = stratwork;
_endWork = endwork;
}
/// <summary>
/// 考勤
/// </summary>
public void Attendance()
{
_checkin.CheckIn(_startWork, _endWork);
}
public DateTime StartWork
{
get
{
return _startWork;
}
set
{
_startWork = value;
}
}
public DateTime EndWork
{
get
{
return _endWork;
}
set
{
_endWork = value;
}
}
}
修改配置文件
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<!-- using embedded assembly configuration file
<resource uri="assembly://Spring.IocQuickStart.MovieFinder/Spring.IocQuickStart.MovieFinder/AppContext.xml"/>
-->
<!-- using section in App.config -->
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<description>An example that demonstrates simple IoC features.</description>
<object id="GeneralStaff"
type="IocExample.GeneralStaff, IocExample">
<property name="checkIn" ref="generalCheckin"/>
</object>
<object id="generalCheckin" type="IocExample.GeneralCheckIn, IocExample" >
</object>
</objects>
</spring>
</configuration>
客服端的代码:
static void Main(string[] args)
{
IApplicationContext context = ContextRegistry.GetContext();
IPersonnel personnel = (IPersonnel)context.GetObject("GeneralStaff");
personnel.StartWork = DateTime.Now;
personnel.EndWork = DateTime.Now.AddHours(8);
personnel.Attendance();
Console.ReadLine();
}
运行结果:

浙公网安备 33010602011771号