前言

  在上一篇我大致的介绍了这个系列所涉及到的知识点,在本篇我打算把IOC这一块单独提取出来讲,因为IOC容器在解除框架层与层之间的耦合有着不可磨灭的作用。当然在本系列前面的三篇中我也提供了一种基于反射的解耦方式,但是始终不是很优雅,运用到项目中显得别扭。目前,我所掌握的IOC容器主要有两个:一个是 unity,另一个则是spring.net,经过慎重的思考我还是决定选择unity 2.0做为本系列的IOC容器,原因主要有两个:第一,他是一个轻量级的容器且师出名门(微软),第二,它提供了简单的拦截机制,在它的基础上实现AOP显得非常的简单,下面开始我们今天的议题......

什么是IOC容器

  IOC容器是对控制反转与依赖注入的一种实现,关于什么是控制反转,什么是依赖注入,网上一搜一大把,我这里就不在多说了,我们需要关注的就是IOC容器到底能够为我们做些什么事情,其实说白了,IOC容器就是通过相应的配置,用来为我们创建实例,使我们摆脱了new的魔咒,这在层与层之间的解耦中有着重要的意义,至于层次间为什么要解耦请参见我的第一篇, 本文着重介绍unity 2.0,您需要在项目中添加对Microsoft.Practices.Unity.dll与Microsoft.Practices.Unity.Configuration.dll的引用,下面我通过简单doom来讲述它的运用,程序如图

企业级应用框架(五)IOC容器在框架中的应用

IOC项目引用了IService项目,但并未引用service项目,IService项目中定义的是服务接口,Service项目引用了IService项目并实现了里面的服务接口。我们现在要做的事情就是在IOC中采用IService接口标识服务,在调用时采用unity容器读取配置文件帮助我们把接口实例化,其具体的服务来自Service项目(我们的IOC项目没有引用Service项目所以是无法new的),为了很好的运用Unity容器,我做了一下封装,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using System.Reflection;

namespace IOC
{
    public class ServiceLocator
    {
        /// <summary>
        /// IOC容器
        /// </summary>
        private readonly IUnityContainer container;
        private static readonly ServiceLocator instance = new ServiceLocator();
        /// <summary>
        /// 服务定位器单例
        /// </summary>
        public static ServiceLocator Instance
        {
            get { return instance; }
        }
        private ServiceLocator()
        {
            //读取容器配置文件
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            //创建容器
            container = new UnityContainer();
            //配置容器
            section.Configure(container);
        }
        #region   
        /// <summary>
        /// 创建构造函数参数
        /// </summary>
        /// <param name="overridedArguments"></param>
        /// <returns></returns>
        private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments)
        {
            List<ParameterOverride> overrides = new List<ParameterOverride>();
            Type argumentsType = overridedArguments.GetType();
            argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .ToList()
                .ForEach(property =>
                {
                    var propertyValue = property.GetValue(overridedArguments, null);
                    var propertyName = property.Name;
                    overrides.Add(new ParameterOverride(propertyName, propertyValue));
                });
            return overrides;
        }
        #endregion


        #region 公共方法
        /// <summary>
        /// 创建指定类型的容器
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetService<T>()
        {
            return container.Resolve<T>();
        }
        /// <summary>
        /// 根据指定名称的注册类型
        /// 创建指定的类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name">注册类型配置节点名称</param>
        /// <returns></returns>
        public T GetService<T>(string name)
        {
            return container.Resolve<T>(name);
        }
        /// <summary>
        /// 用指定的构造函数参数
        /// 创建实体
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="overridedArguments">属性名对应参数名,属性值对应
        /// 参数值得动态参数实体</param>
        /// <returns></returns>
        public T GetService<T>(object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve<T>(overrides.ToArray());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="overridedArguments"></param>
        /// <returns></returns>
        public T GetService<T>(string name,object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve<T>(name, overrides.ToArray());
        }
        #endregion
    }
}
View Code

相关文章: