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();
        }

 运行结果:

demo示例下载

 

posted on 2014-04-04 11:46  khh  阅读(286)  评论(0编辑  收藏  举报

导航