写在前面

  关于Unity的使用可以参照《Unity依赖注入使用详解》,依赖注入的概念参照《小菜学习设计模式(五)—控制反转(Ioc)》。

  在MVC中,控制器依赖于模型对数据进行处理,也可以说执行业务逻辑。我们可以使用依赖注入(DI)在控制层分离模型层,这边要用到Repository模式,在领域驱动设计(DDD)中,Repository翻译为仓储,顾名思义,就是储存东西的仓库,可以理解为一种用来封装存储,读取和查找行为的机制,它模拟了一个对象集合。使用依赖注入(DI)就是对Repository进行管理,用于解决它与控制器之间耦合度问题,下面我们一步一步做一个简单示例。

安装Unity

  首先我们需要新建一个UnityMVCDemo项目(ASP.NET MVC4.0),选择工具-库程序包管理器-程序包管理控制台,输入“Install-Package Unity.Mvc4”命令,VS2010可能需要先安装NuGet。

  或者通过工具-库程序包管理器-管理解决方案的 NuGet 程序包,通过联机搜索“Unity.Mvc4”进行安装。

  在安装过程中可能会遇到下面这样错误:

  根据异常信息,可以肯定是项目的.net framework版本无法安装Unity,这种安装VS会自动搜索Unity最新版本,但是最新版本往往有. net framework版本要求,不知道有没有指定Unity版本安装,可以看到我们安装的是Unity3.0版本,修改一下项目. net framework的版本为4.5,重新安装就可以了。

  安装Unity成功后,我们发现项目中多了“Microsoft.Practices.Unity”和“Microsoft.Practices.Unity.Configuration”两个引用,还有一个Bootstrapper类文件,Bootstrapper翻译为引导程序,也就是Ioc容器。

  1. public static class Bootstrapper
  2. {
  3. public static IUnityContainer Initialise()
  4. {
  5. var container = BuildUnityContainer();
  6.  
  7. DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  8.  
  9. return container;
  10. }
  11.  
  12. private static IUnityContainer BuildUnityContainer()
  13. {
  14. var container = new UnityContainer();
  15.  
  16. // register all your components with the container here
  17. // it is NOT necessary to register your controllers
  18.  
  19. // e.g. container.RegisterType<ITestService, TestService>();
  20. RegisterTypes(container);
  21.  
  22. return container;
  23. }
  24.  
  25. public static void RegisterTypes(IUnityContainer container)
  26. {
  27.  
  28. }
  29. }

添加服务层

  首先我们添加一个Article实体类:

  1. /// <summary>
  2. /// Article实体类
  3. /// </summary>
  4. public class Article
  5. {
  6. public int Id { get; set; }
  7. public string Title { get; set; }
  8. public string Author { get; set; }
  9. public string Content { get; set; }
  10. public DateTime CreateTime { get; set; }
  11. }

  一般Repository都有一些相似的操作,比如增删改查,我们可以把它抽象为IArticleRepository接口,这样控制器依赖于抽象接口,而不依赖于具体实现Repository类,符合依赖倒置原则,我们才可以使用Unity进行依赖注入。

  1. /// <summary>
  2. /// IArticleRepository接口
  3. /// </summary>
  4. public interface IArticleRepository
  5. {
  6. IEnumerable<Article> GetAll();
  7. Article Get(int id);
  8. Article Add(Article item);
  9. bool Update(Article item);
  10. bool Delete(int id);
  11. }

  创建ArticleRepository,依赖于IArticleRepository接口,实现基本操作。

  1. public class ArticleRepository : IArticleRepository
  2. {
  3. private List<Article> Articles = new List<Article>();
  4.  
  5. public ArticleRepository()
  6. {
  7. //添加演示数据
  8. Add(new Article { Id = , Title = "UnityMVCDemo1", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
  9. Add(new Article { Id = , Title = "UnityMVCDemo2", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
  10. Add(new Article { Id = , Title = "UnityMVCDemo2", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
  11. }
  12. /// <summary>
  13. /// 获取全部文章
  14. /// </summary>
  15. /// <returns></returns>
  16. public IEnumerable GetAll()
  17. {
  18. return Articles;
  19. }
  20. /// <summary>
  21. /// 通过ID获取文章
  22. /// </summary>
  23. /// <param name="id"></param>
  24. /// <returns></returns>
  25. public Article Get(int id)
  26. {
  27. return Articles.Find(p => p.Id == id);
  28. }
  29. /// <summary>
  30. /// 添加文章
  31. /// </summary>
  32. /// <param name="item"></param>
  33. /// <returns></returns>
  34. public Article Add(Article item)
  35. {
  36. if (item == null)
  37. {
  38. throw new ArgumentNullException("item");
  39. }
  40. Articles.Add(item);
  41. return item;
  42. }
  43. /// <summary>
  44. /// 更新文章
  45. /// </summary>
  46. /// <param name="item"></param>
  47. /// <returns></returns>
  48. public bool Update(Article item)
  49. {
  50. if (item == null)
  51. {
  52. throw new ArgumentNullException("item");
  53. }
  54.  
  55. int index = Articles.FindIndex(p => p.Id == item.Id);
  56. if (index == -)
  57. {
  58. return false;
  59. }
  60. Articles.RemoveAt(index);
  61. Articles.Add(item);
  62. return true;
  63. }
  64. /// <summary>
  65. /// 删除文章
  66. /// </summary>
  67. /// <param name="id"></param>
  68. /// <returns></returns>
  69. public bool Delete(int id)
  70. {
  71. Articles.RemoveAll(p => p.Id == id);
  72. return true;
  73. }
  74. }

IArticleRepository类型映射

  上面工作做好后,我们需要在Bootstrapper中的BuildUnityContainer方法添加此类型映射。

  1. private static IUnityContainer BuildUnityContainer()
  2. {
  3. var container = new UnityContainer();
  4.  
  5. // register all your components with the container here
  6. // it is NOT necessary to register your controllers
  7.  
  8. container.RegisterType<IArticleRepository, ArticleRepository>();
  9.  
  10. // e.g. container.RegisterType<ITestService, TestService>();
  11. RegisterTypes(container);
  12.  
  13. return container;
  14. }

  我们还可以在配置文件中添加类型映射,UnityContainer根据配置信息,自动注册相关类型,这样我们就只要改配置文件了,当然推荐是这种方法,配置文件:

  1. <configSections>
  2. <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
  3. Microsoft.Practices.Unity.Configuration" />
  4. </configSections>
  5. <unity>
  6. <containers>
  7. <container name="defaultContainer">
  8. <register type="UnityMVCDemo.Models.IArticleRepository, UnityMVCDemo" mapTo="UnityMVCDemo.Models.ArticleRepository, UnityMVCDemo"/>
  9. </container>
  10. </containers>
  11. </unity>

  注意configSections节点要放在configuration节点下的第一个节点,关于Unity的配置文件配置参照http://www.cnblogs.com/xishuai/p/3670292.html,加载配置文件代码:

  1. UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
  2. configuration.Configure(container, "defaultContainer");

  上面这段代码替换掉上面使用的RegisterType方法。

服务注入到控制器

  在ArticleController中我们使用是构造器注入方式,当然还有属性注入和方法注入,可以看到ArticleController依赖于抽象IArticleRepository接口,而并不是依赖于ArticleRepository具体实现类。

  1. public class ArticleController : Controller
  2. {
  3. readonly IArticleRepository repository;
  4. //构造器注入
  5. public ArticleController(IArticleRepository repository)
  6. {
  7. this.repository = repository;
  8. }
  9.  
  10. public ActionResult Index()
  11. {
  12. var data = repository.GetAll();
  13. return View(data);
  14. }
  15. }

Global.asax初始化

  做完上面的工作后,我们需要在Global.asax中的Application_Start方法添加依赖注入初始化。

  1. // Note: For instructions on enabling IIS6 or IIS7 classic mode,
  2. // visit http://go.microsoft.com/?LinkId=9394801
  3. public class MvcApplication : System.Web.HttpApplication
  4. {
  5. protected void Application_Start()
  6. {
  7. AreaRegistration.RegisterAllAreas();
  8.  
  9. WebApiConfig.Register(GlobalConfiguration.Configuration);
  10. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  11. RouteConfig.RegisterRoutes(RouteTable.Routes);
  12.  
  13. Bootstrapper.Initialise();
  14. }
  15. }

后记

  示例代码下载:http://pan.baidu.com/s/1qWoCy9e

  如果你觉得本篇文章对你有所帮助,请点击右下部“推荐”,^_^

ASP.NET MVC中使用Unity Ioc Container的更多相关文章

  1. MVC中使用Unity Ioc Container

    ASP.NET MVC中使用Unity Ioc Container   写在前面 安装Unity 添加服务层 IArticleRepository类型映射 服务注入到控制器 Global.asax初始 ...

  2. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  3. 在ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的 Controller,让Controller ...

  4. IOC 容器在 ASP.NET MVC 中的应用

    IOC 容器在 ASP.NET MVC 中的应用 IOC:Inversion Of Control 翻译为控制反转,我们在面向对象软件开发过程中,一个应用程序它的底层结构可能由N种不同的构件来相互协作 ...

  5. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  6. 在ASP.NET MVC中使用Castle Windsor

    平常用Inject比较多,今天接触到了Castle Windsor.本篇就来体验其在ASP.NET MVC中的应用过程. Visual Studio 2012创建一个ASP.NET MVC 4网站. ...

  7. Asp.net Mvc中利用ValidationAttribute实现xss过滤

    在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...

  8. [转]ASP.NET MVC中你必须知道的13个扩展点

    本文转自:http://www.cnblogs.com/ejiyuan/archive/2010/03/09/1681442.html ScottGu在其最新的博文中推荐了Simone Chiaret ...

  9. Asp.net mvc 中Action 方法的执行(二)

    [toc] 前面介绍了 Action 执行过程中的几个基本的组件,这里介绍 Action 方法的参数绑定. 数据来源 为 Action 方法提供参数绑定的原始数据来源于当前的 Http 请求,可能包含 ...

随机推荐

  1. C# 读取XML注释

    C#可以通过反射读取类的字段/方法等,可是该如何获取该字段的XML注释? 具体目的:有一个实体类,页面需要有一个与其对应的table,样式大体为 <tr> <td>地东经< ...

  2. Angular 1.x 升级到 Angular 2

    原项目用ng1.5写的,现在改成ng2.0了,踩了不少坑,不过都忘记了. 如果你也正好要做这个工作,正好看到这个文章,不妨参考下. AngularJs 1.x -> 2.0 ng-repeat ...

  3. review简历之感想和建议

    最近帮很多朋友review他们的简历,总结起来存在以下问题: 1,简历太多页了.请尽量不超过两页.一般地,每个hr阅读简历的时间大概在20s甚至更少,写那么多页不仅毫无必要,而且有害. 而且我怀疑一般 ...

  4. ASP.NET Aries 开源开发框架:开发指南(一)

    前言: 上周开源了Aries开发框架后,好多朋友都Download了源码,在运行过程里,有一些共性的问题会问到. 所以本篇打算写一下简单的开发指南,照顾一下不是太看的懂源码的同学,同时也会讲解一下框架 ...

  5. 微软“.Net社区虚拟大会”dotnetConf2015 第二天 无处不在的Xamarin

    今天,微软召开了“.Net 社区虚拟大会”(dotnetConf),包括微软的 Scott Hanselman 和 Xamarin 的 Miguel De Icaza 在内的知名人士,都将在 Chan ...

  6. 利用SSH Filesystem实现远程文件系统

         远程文件系统的访问有很多种不同的实现方式,一些常见的连接方式比其它特定情况下的更有用.最著名的一个例子就是微软的通用互联网文件系统(CIFS),它可以容许微软Windows"映射网 ...

  7. 解读ASP.NET 5 & MVC6系列(6):Middleware详解

    在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章我们就来一一分析,在这里如 ...

  8. 一步步学习javascript基础篇(2):作用域和作用域链

    作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...

  9. 记录Office Add-in开发经验

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com 得益于微软系强大的共通能力和Visual Studio的开发支持,做Office插件不是什么难事.一点经验记录如下 ...

  10. C#设计模式之观察者

    Iron之观察者 引言 上一篇说的职责链模式,很有意思的一个模式,今天这个模式也是很有意思的一个模式,还是不啰嗦了直接进入主题吧. 场景介绍:在上一遍中说到用到部件检测,很巧妙的让调用者和处理者解耦了 ...