您当前的位置: 首页 > 技术文章 > 编程语言

ASP.NET MVC IOC 之AutoFac攻略

作者:licqi 时间:2017-01-04阅读数:人阅读

一、为什么使用AutoFac?

之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天,发现这个东东确实是个高大上的IOC容器~

Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个:

优点:

  • 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用,例如可以用Lambda表达式注册组件

  • 较低的学习曲线,学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们

  • XML配置支持

  • 自动装配

  • 与Asp.Net MVC 3集成

  • 微软的Orchad开源程序使用的就是Autofac,从该源码可以看出它的方便和强大

既然它都这么牛X了,我们用它就理所当然了,所以推荐其为IOC的终极解决方案!

二、AutoFac的使用

首先你必须获取AutoFac,这里你可以通过各种方式加载它,我这里还是通过VS中的NuGet来加载AutoFac,不论是哪种方式,最终的目的就是将 Autofac.dll,Autofac.Configuration.dll 这两个程序集引用到你的项目中。这样在你的项目中,如果想使用AutoFac,只需添加其命名空间引用即可~

1、AutoFac入门

我们先定义一个数据访问的接口:

  1. public interface IDAL  
  2. {  
  3.     void Insert(string commandText);  

然后用Sql和Oracle两种方式分别实现上述接口,不过这里只是演示而已,所以并没有真正去实现这两个类,你懂的~

SQL方式:

  1. public class SqlDAL : IDAL  
  2. {  
  3.     public void Insert(string commandText)  
  4.     {  
  5.         Console.WriteLine("使用sqlDAL添加相关信息");  
  6.     }  

Oracle方式:

  1. public class OracleDAL : IDAL  
  2. {  
  3.     public void Insert(string commandText)  
  4.     {  
  5.         Console.WriteLine("使用OracleDAL添加相关信息");  
  6.     }  

然后注入实现构造函数注入:

  1. public class DBManager   
  2. {   
  3.     IDAL _dal;  
  4.     public DBManager(IDAL dal)   
  5.     {   
  6.         _dal= dal;  
  7.     }  
  8. public void Add(string commandText)   
  9.     {   
  10.         _dal.Insert(commandText);   
  11.     }  

最后要真正完成依赖注入就得AtuoFac登场了:

  1. var builder = new ContainerBuilder();   
  2. builder.RegisterType<DBManager>();   
  3. builder.RegisterType<SqlDAL>().As<IDAL>();   
  4. using (var container = builder.Build())   
  5. {   
  6.     var manager = container.Resolve<DBManager>();   
  7.     manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')");   

从以上栗子可以看出,其实AutoFac的使用跟Unity的使用有点像,关键的东东就是这个Container容器类

2、AutoFac常用方法说明

(1)builder.RegisterType<Object>().As<Iobject>():注册类型及其实例。例如下面就是注册接口IDAL的实例SqlDAL

  1. ContainerBuilder builder = new ContainerBuilder();  
  2. builder.RegisterType<SqlDAL>().As<IDAL>();  
  3. IContainer container = builder.Build();  
  4. SqlDAL sqlDAL = (SqlDAL)container.Resolve<IDAL>(); 

(2)IContainer.Resolve<IDAL>():解析某个接口的实例。例如上面的最后一行代码就是解析IDAL的实例SqlDAL

(3)builder.RegisterType<Object>().Named<Iobject>(string name):为一个接口注册不同的实例。有时候难免会碰到多个类映射同一个接口,比如SqlDAL和OracleDAL都实现了IDAL接口,为了准确获取想要的类型,就必须在注册时起名字。

  1. builder.RegisterType<SqlDAL>().Named<IDAL>("sql");  
  2. builder.RegisterType<OracleDAL>().Named<IDAL>("oracle");  
  3. IContainer container = builder.Build();  
  4. SqlDAL sqlDAL = (SqlDAL)container.ResolveNamed<IDAL>("sql");  
  5. OracleDAL oracleDAL = (OracleDAL)container.ResolveNamed<IDAL>("oracle"); 

(4)IContainer.ResolveNamed<IDAL>(string name):解析某个接口的“命名实例”。例如上面的最后一行代码就是解析IDAL的命名实例OracleDAL

(5)builder.RegisterType<Object>().Keyed<Iobject>(Enum enum):以枚举的方式为一个接口注册不同的实例。有时候我们会将某一个接口的不同实现用枚举来区分,而不是字符串,例如:

  1. public enum DBType{ Sql, Oracle} 
  1. builder.RegisterType<SqlDAL>().Keyed<IDAL>(DBType.Sql);  
  2. builder.RegisterType<OracleDAL>().Keyed<IDAL>(DBType.Oracle);  
  3. IContainer container = builder.Build();  
  4. SqlDAL sqlDAL = (SqlDAL)container.ResolveKeyed<IDAL>(DBType.Sql);  
  5. OracleDAL oracleDAL = (OracleDAL)container.ResolveKeyed<IDAL>(DBType.Oracle); 

(6)IContainer.ResolveKeyed<IDAL>(Enum enum):根据枚举值解析某个接口的特定实例。例如上面的最后一行代码就是解析IDAL的特定实例OracleDAL

(7)builder.RegisterType<Worker>().InstancePerDependency():用于控制对象的生命周期,每次加载实例时都是新建一个实例,默认就是这种方式

(8)builder.RegisterType<Worker>().SingleInstance():用于控制对象的生命周期,每次加载实例时都是返回同一个实例

(9)IContainer.Resolve<T>(NamedParameter namedParameter):在解析实例T时给其赋值

  1. DBManager manager = container.Resolve<DBManager>(new NamedParameter("name""SQL")); 
  1. public class DBManager   
  2. {     
  3.     IDAL dal;  
  4.     public DBManager (string name,IDAL  _dal)  
  5.     {  
  6.         Name = name;  
  7.         dal= _dal;  
  8.     }  

3、通过配置的方式使用AutoFac

(1)先配置好配置文件

  1. <?xml version="1.0"?> 
  2. <configuration> 
  3.   <configSections> 
  4.     <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> 
  5.   </configSections> 
  6.   <autofac defaultAssembly="ConsoleApplication1"> 
  7.     <components> 
  8.       <component type="ConsoleApplication1.SqlDAL, ConsoleApplication1" service="ConsoleApplication1.IDAL" /> 
  9.     </components> 
  10.   </autofac> 
  11. </configuration> 

(2)读取配置实现依赖注入(注意引入Autofac.Configuration.dll)

  1. static void Main(string[] args)  
  2.     {  
  3.         ContainerBuilder builder = new ContainerBuilder();  
  4.         builder.RegisterType<DBManager>();  
  5.         builder.RegisterModule(new ConfigurationSettingsReader("autofac"));  
  6.         using (IContainer container = builder.Build())  
  7.         {  
  8.             DBManager manager = container.Resolve<DBManager>();  
  9.             manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')");   
  10.     }  

三、ASP.NET MVC与AtuoFac

终于到了ASP.NET MVC与AtuoFac双剑合璧的时候了,下面就看看AtuoFac在MVC中的应用,其实很简单,大概就几个步骤搞定:

1、首先在函数Application_Start() 注册自己的控制器类,一定要引入Autofac.Integration.Mvc.dll

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Http;  
  6. using System.Web.Mvc;  
  7. using System.Web.Optimization;  
  8. using System.Web.Routing;  
  9. using Autofac;  
  10. using AtuoFacOfMVC4.Models;  
  11. using System.Reflection;  
  12. using Autofac.Integration.Mvc;  
  13.  
  14.  
  15. namespace AtuoFacOfMVC4  
  16. {  
  17.    public class MvcApplication : System.Web.HttpApplication  
  18.     {  
  19.         protected void Application_Start()  
  20.         {  
  21.             var builder = new ContainerBuilder();  
  22.             SetupResolveRules(builder);  
  23.             builder.RegisterControllers(Assembly.GetExecutingAssembly());  
  24.             var container = builder.Build();  
  25.             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));  
  26.  
  27.             AreaRegistration.RegisterAllAreas();  
  28.             WebApiConfig.Register(GlobalConfiguration.Configuration);  
  29.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  30.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  31.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  32.             AuthConfig.RegisterAuth();  
  33.         }  
  34.         private void SetupResolveRules(ContainerBuilder builder)  
  35.         {  
  36.             builder.RegisterType<StudentRepository>().As<IStudentRepository>();  
  37.         }  
  38.     }  

2、现在在你的MVC程序中注入依赖代码就ok了

(1)首先声明一个Student学生类

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.  
  6. namespace AtuoFacOfMVC4.Models  
  7. {  
  8.     public class Student  
  9.     {  
  10.         public int Id { get; set; }  
  11.         public string Name { get; set; }  
  12.         public string Graduation { get; set; }  
  13.         public string School { get; set; }  
  14.         public string Major { get; set; }  
  15.     }  
  16. }  

(2)然后声明仓储接口及其实现

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.  
  6. namespace AtuoFacOfMVC4.Models  
  7. {  
  8.     public interface IStudentRepository  
  9.     {  
  10.         IEnumerable<Student> GetAll();  
  11.         Student Get(int id);  
  12.         Student Add(Student item);  
  13.         bool Update(Student item);  
  14.         bool Delete(int id);  
  15.     }  
  16. }  
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.  
  6. namespace AtuoFacOfMVC4.Models  
  7. {  
  8.     public class StudentRepository : IStudentRepository  
  9.     {  
  10.         private List<Student> Articles = new List<Student>();  
  11.  
  12.         public StudentRepository()  
  13.         {  
  14.             //添加演示数据  
  15.             Add(new Student { Id = 1, Name = "张三", Major = "软件工程", Graduation = "2013年", School = "西安工业大学" });  
  16.             Add(new Student { Id = 2, Name = "李四", Major = "计算机科学与技术", Graduation = "2013年", School = "西安工业大学" });  
  17.             Add(new Student { Id = 3, Name = "王五", Major = "自动化", Graduation = "2013年", School = "西安工业大学" });  
  18.         }  
  19.         /// <summary>  
  20.         /// 获取全部学生信息  
  21.         /// </summary>  
  22.         /// <returns></returns>  
  23.         public IEnumerable<Student> GetAll()  
  24.         {  
  25.             return Articles;  
  26.         }  
  27.         /// <summary>  
  28.         /// 通过ID获取学生信息  
  29.         /// </summary>  
  30.         /// <param name="id"></param>  
  31.         /// <returns></returns>  
  32.         public Student Get(int id)  
  33.         {  
  34.             return Articles.Find(p => p.Id == id);  
  35.         }  
  36.         /// <summary>  
  37.         /// 添加学生信息  
  38.         /// </summary>  
  39.         /// <param name="item"></param>  
  40.         /// <returns></returns>  
  41.         public Student Add(Student item)  
  42.         {  
  43.             if (item == null)  
  44.             {  
  45.                 throw new ArgumentNullException("item");  
  46.             }  
  47.             Articles.Add(item);  
  48.             return item;  
  49.         }  
  50.         /// <summary>  
  51.         /// 更新学生信息  
  52.         /// </summary>  
  53.         /// <param name="item"></param>  
  54.         /// <returns></returns>  
  55.         public bool Update(Student item)  
  56.         {  
  57.             if (item == null)  
  58.             {  
  59.                 throw new ArgumentNullException("item");  
  60.             }  
  61.  
  62.             int index = Articles.FindIndex(p => p.Id == item.Id);  
  63.             if (index == -1)  
  64.             {  
  65.                 return false;  
  66.             }  
  67.             Articles.RemoveAt(index);  
  68.             Articles.Add(item);  
  69.             return true;  
  70.         }  
  71.         /// <summary>  
  72.         /// 删除学生信息  
  73.         /// </summary>  
  74.         /// <param name="id"></param>  
  75.         /// <returns></returns>  
  76.         public bool Delete(int id)  
  77.         {  
  78.             Articles.RemoveAll(p => p.Id == id);  
  79.             return true;  
  80.         }  
  81.     }  

(3)最后添加控制器StudentController,并注入依赖代码

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using AtuoFacOfMVC4.Models;  
  7.  
  8. namespace AtuoFacOfMVC4.Controllers  
  9. {  
  10.     public class StudentController : Controller  
  11.     {  
  12.         readonly IStudentRepository repository;  
  13.         //构造器注入  
  14.         public StudentController(IStudentRepository repository)  
  15.         {  
  16.             this.repository = repository;  
  17.         }  
  18.  
  19.         public ActionResult Index()  
  20.         {  
  21.             var data = repository.GetAll();  
  22.             return View(data);  
  23.         }  
  24.  
  25.     }  

(4)最后为控制器StudentController的Index方法添加视图即可,这里不再详述,运行效果如下

ASP.NET MVC IOC 之AutoFac攻略(图1)

*将自己学习的点滴记录并分享出来,既能使自己得到成长,偶尔也能帮助一下别人,何乐而不为呢?如果这篇文章对你还有点用的话,希望帮忙推荐一下~

原文链接:http://www.cnblogs.com/WeiGe/p/3871451.html

【编辑推荐】

  1. MVC3不能正确识别JSON中的Enum枚举值
  2. ASP.NET入驻Github 下一代ASP.NET将全部开源
  3. 谁说.net 不上档次?让 Asp.net 在 MAC 上飞
  4. ASP.NET MVC Bootstrap极速开发框架
  5. Asp.Net MVC中使用ACE模板之Jqgrid

本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:licqi@yunshuaiweb.com

加载中~
如果您对我们的成果表示认同并且觉得对你有所帮助可以给我们捐赠。您的帮助是对我们最大的支持和动力!
捐赠我们
扫码支持 扫码支持
扫码捐赠,你说多少就多少
2
5
10
20
50
自定义
您当前余额:元
支付宝
微信
余额

打开支付宝扫一扫,即可进行扫码捐赠哦

打开微信扫一扫,即可进行扫码捐赠哦

打开QQ钱包扫一扫,即可进行扫码捐赠哦

天猫38节现货-全屋智能