AutoFac

 一、前言

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

  对于IOC、DI相关的概念由于自己也是一知半解的,推荐T2噬菌体的这篇 依赖注入那些事儿 写的很详细也很好理解。

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

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

  PS:我是采用xml进行配置的AutoFac,如果你采用json进行配置,则需要引用_Microsoft.Extensions.Configuration.Xml_,使用nuget即可获取到这些引用dll。

 二、实例

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

  PSU.Factory:autofac配置相关信息

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

  PSU.IService:功能接口

  PSU.Controllers:控制器

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

1 1 //----------------------------------------------------------------------- 2 2 // <copyright file= "IIndex.cs"> 3 3 // Copyright (c) Danvic712. All rights reserved. 4 4 // </copyright> 5 5 // Author: Danvic712 6 6 // Date Created: 2018/1/9 星期二 16:37:48 7 7 // Modified by: 8 8 // Description: 管理员首页操作邻域 9 9 //----------------------------------------------------------------------- 1010 using PSU.Models.Area.Administrator.Home; 1111 using System; 1212 using System.Collections.Generic; 1313 using System.Linq; 1414 using System.Text; 1515 using System.Threading.Tasks; 1616 1717 namespace PSU.IService.Area.Administrator.Home 1818 { 1919 public interface IIndex 2020 { 2121 /// <summary> 2222 /// 页面初始化加载 2323 /// </summary> 2424 /// <param name="webModel"></param> 2525 /// <returns></returns> 2626 IndexWebModel Init(IndexWebModel webModel); 2727 } 2828 }

接口定义

1 1 //----------------------------------------------------------------------- 2 2 // <copyright file= "IndexDomain.cs"> 3 3 // Copyright (c) Danvic712. All rights reserved. 4 4 // </copyright> 5 5 // Author: Danvic712 6 6 // Date Created: 2018/1/9 星期二 16:42:53 7 7 // Modified by: 8 8 // Description: 管理员首页操作邻域接口实现 9 9 //----------------------------------------------------------------------- 1010 using PSU.IService.Area.Administrator.Home; 1111 using PSU.Models.Area.Administrator.Home; 1212 using System; 1313 1414 namespace PSU.Domain.Area.Administrator.Home 1515 { 1616 public class IndexDomain : IIndex 1717 { 1818 /// <summary> 1919 /// 页面初始化加载 2020 /// </summary> 2121 /// <param name="webModel"></param> 2222 /// <returns></returns> 2323 public IndexWebModel Init(IndexWebModel webModel) 2424 { 2525 webModel = new IndexWebModel(); 2626 return webModel; 2727 } 2828 } 2929 }

接口实现类

   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 1 //----------------------------------------------------------------------- 2 2 // <copyright file= "MAutoFac.cs"> 3 3 // Copyright (c) Danvic712. All rights reserved. 4 4 // </copyright> 5 5 // Author: Danvic712 6 6 // Date Created: 2018/1/8 星期一 13:23:04 7 7 // Modified by: 8 8 // Description: AutoFac帮助类 9 9 //----------------------------------------------------------------------- 1010 using Autofac; 1111 using Autofac.Configuration; 1212 using Microsoft.Extensions.Configuration; 1313 1414 namespace PSU.Factory 1515 { 1616 public class MAutoFac 1717 { 1818 /// <summary> 1919 /// 缓存注册容器 2020 /// </summary> 2121 private static IContainer _container = null; 2222 2323 /// <summary> 2424 /// 注册并创建实例 2525 /// </summary> 2626 /// <typeparam name="T"></typeparam> 2727 /// <returns></returns> 2828 public static T CreateInstance<T>() 2929 { 3030 if (_container == null) 3131 { 3232 var builder = new ContainerBuilder(); 3333 3434 //读取配置信息 3535 // 3636 IConfigurationBuilder config = new ConfigurationBuilder(); 3737 config.AddXmlFile("autofac.config"); 3838 3939 //注册组件 4040 var module = new ConfigurationModule(config.Build()); 4141 4242 //注册模块 4343 builder.RegisterModule(module); 4444 4545 _container = builder.Build(); 4646 } 4747 4848 return _container.Resolve<T>(); 4949 } 5050 } 5151 }

帮助类

11 <?xml version="1.0" encoding="utf-8" ?> 22 <autofac defaultAssembly="PSU.IService"> 33 <!--Administrator:首页接口--> 44 <components name="0"> 55 <type>PSU.Domain.Area.Administrator.Home.IndexDomain,PSU.Domain</type> 66 <services name="0" type="PSU.IService.Area.Administrator.Home.IIndex" /> 77 <injectProperties>true</injectProperties> 88 </components> 99 </autofac>

配置文件

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

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

配置相关解释:

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

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

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

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

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

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

1 1 //----------------------------------------------------------------------- 2 2 // <copyright file= "HomeController.cs"> 3 3 // Copyright (c) Danvic712. All rights reserved. 4 4 // </copyright> 5 5 // Author: Danvic712 6 6 // Date Created: 2017/12/20 星期三 14:20:40 7 7 // Modified by: 8 8 // Description: Administrator-Home控制器 9 9 //----------------------------------------------------------------------- 1010 using PSU.Factory; 1111 using PSU.IService.Area.Administrator.Home; 1212 using PSU.Models.Area.Administrator.Home; 1313 using System.Web.Mvc; 1414 using System.Web.Routing; 1515 1616 namespace PSU.Controllers.Areas.Administrator 1717 { 1818 public class HomeController : Controller 1919 { 2020 #region Initializes 2121 2222 private IIndex _iService; 2323 2424 protected override void Initialize(RequestContext requestContext) 2525 { 2626 base.Initialize(requestContext); 2727 2828 if (_iService == null) 2929 { 3030 _iService = MAutoFac.CreateInstance<IIndex>(); 3131 } 3232 } 3333 3434 #endregion 3535 3636 #region Service 3737 3838 public ActionResult Index(IndexWebModel webModel) 3939 { 4040 _iService.Init(webModel); 4141 return View(webModel); 4242 } 4343 4444 #endregion 4545 } 4646 }

控制器

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

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

 三、其它

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

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

  3、个人的一点使用实例,希望对你有点用处,如果中间有说的不对的地方,欢迎指点

  4、欢迎转载,注明出处即可

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )