当前位置: 首页 > news >正文

.Net IOC框架入门之一 Unity

一、概述

  IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection)。
  作用:将各层的对象以松耦合的方式组织在一起,解耦,各层对象的调用完全面向接口。当系统重构的时候,代码的改写量将大大减少。
  依赖注入: 当一个类的实例需要另一个类的实例协助时,在传统的程序设计过程中,通常有调用者来创建被调用者的实例。然而采用依赖注入的方式,创建被调用者的工作不再由调用者来完成,因此叫控制反转,创建被调用者的实例的工作由IOC容器来完成,然后注入调用者,因此也称为依赖注入。

   Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器;

  它支持常用的三种依赖注入方式:构造器注入(Constructor Injection)、属性注入(Property Injection),以及方法调用注入(Method Call Injection)。

  现在Unity最新的版本的4.0版,可以在微软的开源站点 https://github.com/unitycontainer/unity 下载最新的发布版本。

  通过使用Unity,我们能轻松构建松耦合结构的程序,从而让整个程序框架变得清晰和易于维护。

二、简单示例

1.示例1

  创建一个mvc5项目 Web.Mvc,然后在创建一个Business类库,将类库添加引用到Web.Mvc项目,在Web.Mvc项目通过nuget添加unity.mvc5

类库代码

a、Business类库定义一个接口IUserService

复制代码
namespace Business
{
    /// <summary>
    /// 显示信息
    /// </summary>
    public interface IUserService
    {
        string Display(string mes);
    }
}
复制代码

b、Business类库实现接口

复制代码
namespace Business
{
    public class UserService : IUserService
    {
        /// <summary>
        /// 显示信息
        /// </summary>
        /// <param name="mes"></param>
        public string Display(string mes)
        {
            return "I say:" + mes;
        }
    }
}
复制代码

c、注册依赖使用依赖注入生效

在Web.Mvc项目的Global.asax进行注册 

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Business;
using Microsoft.Practices.Unity;
using Unity.Mvc5;

namespace Web.Mvc
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //注入 Ioc
            var container = this.BuildUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }


        IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();
            container.RegisterType<IUserService, UserService>();
            return container;
        }
    }
}
复制代码

d、使用

复制代码
namespace Web.Mvc.Controllers
{
    public class HomeController : Controller
    {

        private IUserService userService;

        public HomeController(IUserService userService)
        {
            this.userService = userService;
        }

        public ActionResult Index()
        {
            ViewBag.Msg = userService.Display("hahaha");
            return View();
        }
   }
}
复制代码

e、在Index.cshtml找个地方写入@ViewBag.Msg 就可以,如

<h1>ASP.NET - @ViewBag.Msg</h1>

最后运行项目,实现效果

ASP.NET - I say:hahaha

三、注册封装

对步骤c 的注册进行独立封装到BootStrapper中

c、注册依赖使用依赖注入生效

在Web.Mvc项目的Global.asax进行注册 

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Business;
using Microsoft.Practices.Unity;
using Unity.Mvc5;

namespace Web.Mvc
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //注入 Ioc 
            BootStrapper.Initialise();
        } 
    }
}
复制代码

BootStrapper代码

复制代码
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Business;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Unity.Mvc5;

namespace Web.Mvc
{
    public class BootStrapper
    {
        /// <summary>
        /// 获取容器-注册依赖关系
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer Initialise()
        {
            var container = BulidUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            return container;
        }

        /// <summary>
        /// 加载容器
        /// </summary>
        /// <returns></returns>
        private static IUnityContainer BulidUnityContainer()
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        }

        /// <summary>
        /// 实施依赖注入
        /// </summary>
        /// <param name="container"></param>
        private static void RegisterTypes(IUnityContainer container)
        { 
            //类型的配置容器注册
            container.RegisterType<IUserService, UserService>();
            //container.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager());//通过生命周期实现了单例模式

            //已有对象实例的配置容器注册,也为单例
            //UserService userService = new UserService(); 
            //container.RegisterInstance<IUserService>(userService);

        }
    }
}
复制代码

Unity注册配置

 修改上面的方法,将注册放到配置文件中

1.方法修改

复制代码
        /// <summary>
        /// 实施依赖注入
        /// </summary>
        /// <param name="container"></param>
        private static void RegisterTypes(IUnityContainer container)
        {
            依赖关系可以选择代码形式,也可以用配置文件的形式
            UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
            config.Configure(container, "defaultContainer"); 
        }
复制代码
UnityConfigurationSection.SectionName为unity

2.配置文件

 提示:自定义web.config节点来实现

复制代码
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
    <!-- 一般将unity节点放到文件末尾 --> 
  </configSections> 
  
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <namespace name="Business" />
    <assembly name="Business" />
    <containers>
      <container name="defaultContainer">
        <register type="IUserService" mapTo="UserService">
          <lifetime type="singleton" />
        </register>
        <register type="ILocalUserService" mapTo="LocalUserService"/>
      </container>
    </containers>
  </unity>
</configuration>
复制代码

或者为

直接指定命名空间

复制代码
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
    <assembly name="Business" />
    <containers>
      <container name="defaultContainer">
        <register type="Business.IUserService" mapTo="Business.UserService">
          <lifetime type="singleton" />
        </register>
        <register type="Business.ILocalUserService" mapTo="Business.LocalUserService"/>
      </container>
    </containers>
  </unity>
复制代码

或者为

指定程序集名称

复制代码
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">  
    <containers>
      <container name="defaultContainer">
        <register type="Business.IUserService,Business" mapTo="Business.UserService,Business">
          <lifetime type="singleton" />
        </register>
        <register type="Business.ILocalUserService,Business" mapTo="Business.LocalUserService,Business"/>
      </container>
    </containers>
  </unity>
复制代码

 

 

 

参考网址:

http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html

https://www.lanhusoft.com/Article/108.html

http://blog.csdn.net/xingxing513234072/article/details/21176247

http://www.cnblogs.com/wwj1992/p/6728370.html

http://www.cnblogs.com/xishuai/p/3670292.html(推荐)

 

 

 
 

相关文章:

  • 过 DNF TP 驱动保护(一)
  • 数组倒序输出
  • EF架构~XMLRepository仓储的实现
  • 上海南站(2007-04-07)
  • ORACLE使用EXPDP和IMPDP数据泵进行导出导入的方法
  • 乾颐堂HCIE面试真题系列4,附考场外景,缓解大家的紧张情绪
  • tomcat访问(access)日志配置、记录Post请求参数
  • 求排列求组合的实现
  • zdz工具箱v1.7版本发布了
  • Python中检查MongoDB的返回结果是否为空
  • BitTorrent (协议)
  • perl 使用小结
  • JS获取屏幕,可见窗口和网页文档(html)大小
  • C# 批量复制文件
  • linux 搭建基于域名的虚拟主机
  • 2017-09-12 前端日报
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • JS专题之继承
  • Python学习之路16-使用API
  • Redash本地开发环境搭建
  • Sublime text 3 3103 注册码
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 翻译:Hystrix - How To Use
  • 分布式事物理论与实践
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 开源SQL-on-Hadoop系统一览
  • 配置 PM2 实现代码自动发布
  • 前端面试总结(at, md)
  • 前端自动化解决方案
  • const的用法,特别是用在函数前面与后面的区别
  • 从如何停掉 Promise 链说起
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​马来语翻译中文去哪比较好?
  • #传输# #传输数据判断#
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (四)图像的%2线性拉伸
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net core webapi 大文件上传到wwwroot文件夹
  • .net wcf memory gates checking failed
  • .Net 代码性能 - (1)
  • .net 后台导出excel ,word
  • @Autowired多个相同类型bean装配问题
  • @JSONField或@JsonProperty注解使用
  • [ Linux ] Linux信号概述 信号的产生
  • [100天算法】-目标和(day 79)
  • [2669]2-2 Time类的定义
  • [51nod1610]路径计数
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [AutoSar]工程中的cpuload陷阱(三)测试