AutoFac - 将 autofac 应用于MVC多层项目

 1、前言

  AutoFac是.NET平台下的一款著名的IoC Container,它可让咱们很轻松的解除项目中服务类的接口与客户类的接口实现类之间的依赖关系,从而下降系统各模块之间耦合程度以提升系统的稳定性。最近在作毕业设计,在开发中采用了autofac来进行依赖注入,这里是对踩到的一些坑的解决方法,但愿能够给一样不幸进入这些坑中的童鞋们提供一些解决思路。html

  对于IOC、DI相关的概念因为本身也是只知其一;不知其二的,推荐T2噬菌体的这篇 依赖注入那些事儿 写的很详细也很好理解。web

  AutoFac文档地址:http://autofac.readthedocs.io/en/latest/getting-started/index.htmljson

  使用AutoFac须要引用的类库dll:Autofac.dllAutofac.ConfigurationMicrosoft.Extensions.Configuration.Xml缓存

  PS:我是采用xml进行配置的AutoFac,若是你采用json进行配置,则须要引用Microsoft.Extensions.Configuration.Xml,使用nuget便可获取到这些引用dll。mvc

 2、实例

  项目结构以下图所示,autofac涉及到类库以下ide

  PSU.Factory:autofac配置相关信息测试

  PSU.Domain:功能接口的实现类网站

  PSU.IService:功能接口ui

  PSU.Controllers:控制器spa

  PSU.IService、PSU.Domain就是基本的接口与其实现类,也就没什么东西了,测试的代码以下:

 1 //-----------------------------------------------------------------------  2 // <copyright file= "IIndex.cs">  3 // Copyright (c) Danvic712. All rights reserved.  4 // </copyright>  5 // Author: Danvic712  6 // Date Created: 2018/1/9 星期二 16:37:48  7 // Modified by:  8 // Description: 管理员首页操做邻域  9 //-----------------------------------------------------------------------
10 using PSU.Models.Area.Administrator.Home; 11 using System; 12 using System.Collections.Generic; 13 using System.Linq; 14 using System.Text; 15 using System.Threading.Tasks; 16 
17 namespace PSU.IService.Area.Administrator.Home 18 { 19     public interface IIndex 20  { 21         /// <summary>
22         /// 页面初始化加载 23         /// </summary>
24         /// <param name="webModel"></param>
25         /// <returns></returns>
26  IndexWebModel Init(IndexWebModel webModel); 27  } 28 }
接口定义
 1 //-----------------------------------------------------------------------  2 // <copyright file= "IndexDomain.cs">  3 // Copyright (c) Danvic712. All rights reserved.  4 // </copyright>  5 // Author: Danvic712  6 // Date Created: 2018/1/9 星期二 16:42:53  7 // Modified by:  8 // Description: 管理员首页操做邻域接口实现  9 //-----------------------------------------------------------------------
10 using PSU.IService.Area.Administrator.Home; 11 using PSU.Models.Area.Administrator.Home; 12 using System; 13 
14 namespace PSU.Domain.Area.Administrator.Home 15 { 16     public class IndexDomain : IIndex 17  { 18         /// <summary>
19         /// 页面初始化加载 20         /// </summary>
21         /// <param name="webModel"></param>
22         /// <returns></returns>
23         public IndexWebModel Init(IndexWebModel webModel) 24  { 25             webModel = new IndexWebModel(); 26             return webModel; 27  } 28  } 29 }
接口实现类

   PSU.Factory这个类库里写的是autofac的配置方法,在写以前让咱们先看看官方的Demo:

   简单翻译一下

  1. 你须要在你的项目里加载Microsoft.Extensions.Configuration 这个dll,若是你使用json进行配置的话,你须要加载 Microsoft.Extensions.Configuration.Json 这个dll,而我是经过xml文件进行配置,则须要加载 Microsoft.Extensions.Configuration.Xml
  2. 经过实例化ConfigurationBuilder来加载配置文件
  3. 注册配置组件
  4. 在容器中注册配置模块

  由于咱们会把全部的接口与实现类的映射放置于xml文件中,将全部的模块注册在容器中,经过对于官方方法的封装,建立一个静态方法去自由的选择加载须要接口与实现类,代码和配置文件以下:

 1 //-----------------------------------------------------------------------  2 // <copyright file= "MAutoFac.cs">  3 // Copyright (c) Danvic712. All rights reserved.  4 // </copyright>  5 // Author: Danvic712  6 // Date Created: 2018/1/8 星期一 13:23:04  7 // Modified by:  8 // Description: AutoFac帮助类  9 //-----------------------------------------------------------------------
10 using Autofac; 11 using Autofac.Configuration; 12 using Microsoft.Extensions.Configuration; 13 
14 namespace PSU.Factory 15 { 16     public class MAutoFac 17  { 18         /// <summary>
19         /// 缓存注册容器 20         /// </summary>
21         private static IContainer _container = null; 22 
23         /// <summary>
24         /// 注册并建立实例 25         /// </summary>
26         /// <typeparam name="T"></typeparam>
27         /// <returns></returns>
28         public static T CreateInstance<T>() 29  { 30             if (_container == null) 31  { 32                 var builder = new ContainerBuilder(); 33 
34                 //读取配置信息 35                 // 36                 IConfigurationBuilder config = new ConfigurationBuilder(); 37                 config.AddXmlFile("autofac.config"); 38 
39                 //注册组件
40                 var module = new ConfigurationModule(config.Build()); 41 
42                 //注册模块
43  builder.RegisterModule(module); 44 
45                 _container = builder.Build(); 46  } 47 
48             return _container.Resolve<T>(); 49  } 50  } 51 }
帮助类
1 <?xml version="1.0" encoding="utf-8" ?>
2 <autofac defaultAssembly="PSU.IService">
3   <!--Administrator:首页接口-->
4   <components name="0">
5     <type>PSU.Domain.Area.Administrator.Home.IndexDomain,PSU.Domain</type>
6     <services name="0" type="PSU.IService.Area.Administrator.Home.IIndex" />
7     <injectProperties>true</injectProperties>
8   </components>
9 </autofac>
配置文件

  建立一个返回类型是泛型的静态方法,经过 Resolve<T>() 用来解析容器中已经注册的实例T,并对给其进行赋值,这样,咱们就能够经过传入指定的接口来获取对应的实现方法。

  对于XML配置文件,若是你是采用VS生成的配置文件模版,你须要移除 configuration 根节点,直接使用 autofac 做为XML文档的根节点,切记,不然你将没法读取到配置信息。同时,若是你是和我同样的直接写好配置文件的地址,你须要将配置文件放置在Web项目的根目录下,或者显示写好加载的配置文件的所在地址。

  配置相关解释:

  一、defaultAssembly 默认的命名空间;若是type节点或者services节点的属性type没有设置类所在命名空间的话,将默认在defaultAssembly下查找类,type节点和services节点的属性type设置格式为MyType,MyAssembly;

  二、多个接口时添加多个components节点,name 属性依次添加;

  三、type节点对应接口实现类所在的位置(命名空间.类名,命名空间) --- 英文逗号;

  四、services节点对应接口所在的位置(命名空间.接口类名)

  五、injectProperties节点:是否启用组件的属性注入

       在控制器调用接口实例,我是采用的重写 Controller 类的 Inintalize 方法,实现接口的注入,这样咱们就能够在控制器中调用接口里的方法了,实现方法以下图所示。

 1 //-----------------------------------------------------------------------  2 // <copyright file= "HomeController.cs">  3 // Copyright (c) Danvic712. All rights reserved.  4 // </copyright>  5 // Author: Danvic712  6 // Date Created: 2017/12/20 星期三 14:20:40  7 // Modified by:  8 // Description: Administrator-Home控制器  9 //-----------------------------------------------------------------------
10 using PSU.Factory; 11 using PSU.IService.Area.Administrator.Home; 12 using PSU.Models.Area.Administrator.Home; 13 using System.Web.Mvc; 14 using System.Web.Routing; 15 
16 namespace PSU.Controllers.Areas.Administrator 17 { 18     public class HomeController : Controller 19  { 20         #region Initializes
21 
22         private IIndex _iService; 23 
24         protected override void Initialize(RequestContext requestContext) 25  { 26             base.Initialize(requestContext); 27 
28             if (_iService == null) 29  { 30                 _iService = MAutoFac.CreateInstance<IIndex>(); 31  } 32  } 33 
34         #endregion
35 
36         #region Service
37 
38         public ActionResult Index(IndexWebModel webModel) 39  { 40  _iService.Init(webModel); 41             return View(webModel); 42  } 43 
44         #endregion
45  } 46 }
控制器

   至此,咱们要完成的也就差很少了,运行项目看看,咦,发现报错,查看报错信息,提示咱们找不到PSU.Domain这个类库dll

  Web项目,它所依赖的dll所有位于网站根目录下面的bin文件夹中,因为咱们采用IOC加载接口实现层,Web层只引用接口,不引用接口实现层,因此autofac没法在项目中找到PSU.Domain这个dll,因此咱们只要把这个dll给移动到Web项目的bin目录下面就能够了。编译生成后手动移动,繁琐、费事。这里我采用的是经过在PSU.Domain这里类库的属性上添加后期生成命令完成操做。从新生成下项目,预览这个视图页面,bingo,能够了。

 

 3、其它

  一、经过属性后期生成事件生成接口实现类库到bin文件夹里,有人说在release模式下,执行失败,我还没到这一步,因此就不得而知了,解决方案能够见连接 =》https://social.msdn.microsoft.com/Forums/zh-CN/caf363ec-e0f9-41da-ad24-60993e83f190/releasebindll?forum=adonetzhchs

  二、代码完成以后,才发现AutoFac有专门的一个在MVC项目如何使用的实例,若是有童鞋用过的话,能够说说这两种的优劣,示例见连接 =》http://autofac.readthedocs.io/en/latest/integration/mvc.html

  三、我的的一点使用实例,但愿对你有点用处,若是中间有说的不对的地方,欢迎指点

  四、欢迎转载,注明出处便可

相关文章
相关标签/搜索