首页 > 代码库 > Unity IoC Base On MVC

Unity IoC Base On MVC

Unity框架,是一个经典的IoC模式实现方式,其通过config文件配置section,将接口与实现解藕,config中的section配置的container以全名称对应,使得应用程序无需像Ninject方式那样,依赖接口项和实现项,因其解藕的配置,能让应用程序实现静态更新服务的效果,即不退出应用程序更新服务的功能。

下面是Unity的实现,其核心接口IUnityContainer是Unity模式实现的基础,在Controller生命周期中IUnityContainer起到传递section配置的作用,在Controller实例化时创建依赖的接口服务的实例对象,当Countroller执行结束后,接口服务的实例对象交由IUnityContainer维护

首先需要安装Unity,引用以下两个dll

技术分享

 

接下来实现Unity的管理类,新建mvc5网站项目,并如下实现

public class UnityControllerFactory : DefaultControllerFactory
    {
        static object syncHelper = new object();
        static Dictionary<string, IUnityContainer> containers = new Dictionary<string, IUnityContainer>();
        public IUnityContainer UnityContainer { get; private set; }
        public UnityControllerFactory(string containerName = "")
        {
            if (containers.ContainsKey(containerName))
            {
                this.UnityContainer = containers[containerName];
                return;
            }
            lock (syncHelper)
            {
                if (containers.ContainsKey(containerName))
                {
                    this.UnityContainer = containers[containerName];
                    return;
                }
                IUnityContainer container = new UnityContainer();
                //配置UnityContainer
                UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
                if (null == configSection && !string.IsNullOrEmpty(containerName))
                {
                    throw new ConfigurationErrorsException("The <unity> configuration section does not exist.");
                }
                if (null != configSection)
                {
                    if (string.IsNullOrEmpty(containerName))
                    {
                        configSection.Configure(container);
                    }
                    else
                    {
                        configSection.Configure(container, containerName);
                    }
                }
                containers.Add(containerName, container);
                this.UnityContainer = containers[containerName];
            }
        }
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (null == controllerType)
            {
                return null;
            }
            return (IController)this.UnityContainer.Resolve(controllerType);
        }
        public override void ReleaseController(IController controller)
        {
            this.UnityContainer.Teardown(controller);
        }
    }

 

假设有一个服务接口在一个独立的C#类库名为MyInterface

public interface IEmployeeRepository
    {
        IEnumerable<Employee> GetEmployees(string id = "");
    }

 

和服务接口的实现项在一个独立的C#类库名为MyService

public class EmployeeRepository: IEmployeeRepository
    {
        private static IList<Employee> employees;
        static EmployeeRepository()
        {
            employees = new List<Employee>();
            employees.Add(new Employee(Guid.NewGuid().ToString(), "张三", "", new DateTime(1981, 8, 24), "销售部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "李四", "", new DateTime(1982, 7, 10), "人事部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "王五", "", new DateTime(1981, 9, 21), "人事部"));
        }
        public IEnumerable<Employee> GetEmployees(string id = "")
        {
            return employees.Where(e => e.Id == id || string.IsNullOrEmpty(id) || id == "*");
        }
    }

 

在上面新建的mvc5网站项目中,引用MyInterface的C#类库,在网站的global文件中Application_Start中添加如下这句,将我们创建的UnityControllerFactory注入给ControllerBuilder初始化

ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());

 

在mvc5网站的web.config中添加section接口服务map信息,将接口与其服务实现类信息配置给Unity

<unity>
    <containers>
      <container>
        <register type="Mvc.IEmployeeRepository, Mvc.MvcApp" 
                  mapTo="Mvc.EmployeeRepository, Mvc.MvcApp"/>
      </container>
    </containers>
  </unity>

 

 Unity与于Ninject的好处很明显,接口与实现解藕,无需直接依赖实现项,达到静态更新的效果,在应用程序运行时,只需将实现项的DLL(此处即为MyService.dll)下载替换,即可实现服务更新,要实现自动化静态更新当然需要做些工作,比如MyService应该需要版本检测及下载功能,有兴趣的可以做做

 

Unity IoC Base On MVC