隐藏

ASP.NET MVC中使用Unity Ioc Container

发布:2018/11/18 11:37:22作者:管理员 来源:本站 浏览次数:1144

写在前面

关于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 = 1, Title = "UnityMVCDemo1", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });  9 Add(new Article { Id = 2, Title = "UnityMVCDemo2", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now }); 10 Add(new Article { Id = 3, 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 == -1) 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

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