经过上篇蜻蜓点水的介绍后,本篇通过实例快速上手autofac,展示当asp.net mvc引入了autofac之后会带来什么。

创建Asp.net MVC并引入Autofac

首先,创建一个MVC站点,为方便起见,选初始带HomeController和AccountController的那种。然后通过NuGet或到Autofac官网下载来引入类库。个人推荐前者,因为从VS2010开始,已内集可视化的NuGet功能,使用起来非常方便。如下图所示:

这是vs2012的界面,点击“Manage NuGet Packages…”,弹出窗体如下,在右上角搜索框中输入“Autofac”,找到对应的库点击安装即可。这里需要应用的库有两个“Autofac”和“Autofac ASP.Net MVC3 Integration”。

autofac实现对Controller的自动注入

现在HomeController需要用到日志记录功能。沿用上篇ILog接口,假设目前已有一种ILog的实现类--TxtLog,放在根目录下Services文件夹中。

public class TxtLog:ILog  
{  
    public void Save(string message)  
    {  
        //save as txt  
    }  
}

HomeController需添加一个ILog类型变量,为了直观看到类名,我把_log的类名赋给ViewBag.LogTypeName并显示出来。代码如下:

public class HomeController : Controller  
{  
    private ILog _log;  
            
    public HomeController(ILog log)  
    {  
        _log = log;  
    }  
        
    public ActionResult Index()  
    {  
        ViewBag.Message = "Welcome to ASP.NET MVC!";  
        ViewBag.LogTypeName = _log.GetType().Name;  
               
        return View();  
    }  
        
    //....

接着,在对应页面加入以下代码(抱歉这里用英文描述,因为我的代码高亮插件不能显示中文):

<h2>ILog's type name is @ViewBag.LogTypeName</h2>

此时运行程序会报错,因为HomeController找不到无参构造函数,而我们也没有给_log指定任何类型的实例。

现在我们让Autofac发挥作用,在Global文件的Application_Start方法中添加配置代码,如下:

protected void Application_Start()  
{  
    ......  
        
    ContainerBuilder builder = new ContainerBuilder();  
    builder.RegisterControllers(Assembly.GetExecutingAssembly());  
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())  
        .AsImplementedInterfaces();  
            
    var container = builder.Build();  
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));  
}

先不管含义,加了这些代码以后,再运行程序,会发现HomeController的ILog变量被赋予了TxtLog类型的实例,而我们并没有做任何new操作,结果如下图:

autofac应对需求变更

回头再看Application_Start中配置文件的代码:

  1. builder.RegisterControllers注册了当前程序集内所有的Controller类。

  2. builder.RegisterAssemblyTypes注册了当前程序集内的所有类。

如果此刻需求改变,我们需要将所有的TxtLog换成DbLog,该怎么办?首先添加DBLog类,如下:

public class DbLog:ILog  
{  
    public void Save(string message)  
    {  
        //save to Db.  
    }  
}

然后在Application_Start的方法的末端处添加如下代码:

builder.RegisterType<DbLog>().As<ILog>();

运行程序,看到页面如下:

可看出ILog的类型已变成了DbLog。但为何要强调末端处?实际上,DBLog已经通过builder.RegisterAssemblyTypes被注册过一次,如果对同一个类型或接口注册多次(比如这里的ILog),在Autofac中会以列表的形式保存,如果只取一个,则Autofac会从列表返回最新的那个。

为了证明,我们在HomeController中再加入一个变量,类型为IEnumerable<ILog>,然后将列表中所有类名显示出来,用逗号隔开。

public class HomeController : Controller  
{  
    private ILog _log;  
    private IEnumerable<ILog> _logList;  
    public HomeController(ILog log,IEnumerable<ILog> logList )  
    {  
        _log = log;  
        _logList = logList;  
    }  
        
    public ActionResult Index()  
    {  
        ViewBag.Message = "Welcome to ASP.NET MVC!";  
        ViewBag.LogTypeName = _log.GetType().Name;  
        ViewBag.LogTypeNames = _logList.Select(x => x.GetType().Name).Aggregate((x, y) => x+","+y );  
                
        return View();  
    }

运行程序,页面显示如下:

可以看到,针对ILog接口注册了三个类型。前两个通过builder.RegisterAssemblyTypes注册,最后一个是我们手动添加。

但重复的注册类型总让人觉得不够优雅,因此实际开发中并不推荐一次性注册所有类,可条件筛选。翻开Autofac的源码,查看我们上文用到的builder.RegisterControllers会发现方法内部就是这种思路:

public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle>  
    RegisterControllers(  
        this ContainerBuilder builder,  
        params Assembly[] controllerAssemblies)  
{  
    return builder.RegisterAssemblyTypes(controllerAssemblies)  
        .Where(t => typeof(IController).IsAssignableFrom(t) &&  
            t.Name.EndsWith("Controller"));  
}

由代码可知,该方法筛选出所有实现IController接口且类型名以“Controller”结尾的类。你可以根据自己项目的实际情况来筛选,很多使用Autofac的开源站点也都是这么做的。

Ioc容器Autofac系列(2)-- asp.net mvc中整合autofac的更多相关文章

  1. Asp.net mvc中整合autofac

    创建Asp.net MVC并引入Autofac 首先,创建一个MVC站点,为方便起见,选初始带HomeController和AccountController的那种.然后通过NuGet或到Autofa ...

  2. asp.net MVC中使用Autofac小结 (遇到的最傻错误: 没有为该对象定义无参数的构造函数)

    项目使用的MVC4,.net 4.5 Nuget安装最新的autofac,一直提示不支持.net 4.5.没办法了,最后用Nuget控制台安装的老版本.因为我使用的是MVC4,所以直接安装的是auto ...

  3. 如何在asp.net mvc 中使用Autofac 控制反转(Ioc)

    前言 最近看了一些关于Ioc方面的开源项目,里面的类跳来转去,看的迷迷糊糊的.项目里根本不需要这么“复杂的”设计,只需简单完成Ico,达到解耦的目的,并且能高效的完成项目.于是参考autofac的官网 ...

  4. Asp.net mvc中应用autofac

    1.nuget安装依赖

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

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

  6. ASP.NET MVC3 中整合 NHibernate3.3、Spring.NET2.0 时 Session 关闭问题

    一.问题描述 在向ASP.NET MVC中整合NHibernate.Spring.NET后,如下管理员与角色关系: 类public class Admin { public virtual strin ...

  7. 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, ...

  8. ASP.NET MVC中使用Unity Ioc Container

    写在前面 安装Unity 添加服务层 IArticleRepository类型映射 服务注入到控制器 Global.asax初始化 后记 关于Unity的使用可以参照<Unity依赖注入使用详解 ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

随机推荐

  1. 原创-兼容IE8的placeholder

    !function (o) { o.fn.extend({ PlaceHolder: function () { var _isEmpty = function (val) { return (val ...

  2. C#基本知识点-Readonly和Const的区别

    什么是静态常量(Const)和动态常量(Readonly)   先解释下什么是静态常量(Const)以及什么是动态常量(Readonly). 静态常量(Const)是指编译器在编译时候会对常量进行解析 ...

  3. HDU 1695 (莫比乌斯反演) GCD

    题意: 从区间[1, b]和[1, d]中分别选一个x, y,使得gcd(x, y) = k, 求满足条件的xy的对数(不区分xy的顺序) 分析: 虽然之前写过一个莫比乌斯反演的总结,可遇到这道题还是 ...

  4. 微信分享自定义图片标题摘要-微信官方API

    我们平时在使用微信内置浏览器打开网页想要分享给好友或者发到朋友圈的时候经常会遇到这样的问题, 别人的网页分享的时候是这样的: 而我们自己的网页分享后这这样的: 看到有人说不做任何设置,微信分享时会自动 ...

  5. 转:ASP.NET MVC中Unobtrusive Ajax的妙用

    Unobtrusive Javascript有三层含义:一是在HTML代码中不会随意的插入Javsscript代码,只在标签中加一些额外的属性值,然后被引用的脚本文件识别和处理:二是通过脚本文件所增加 ...

  6. Repeater 控件 当数据源没有数据的时候显示 暂无数据 的两种方式

    第一种:现在前台给Repeater控件外面的div加一个runat=”server”  然后在cs后台判断数据源是否为空, 是的话就修改这个前台div的InnerText或者是InnerHtml 即可 ...

  7. 【JS】js获得下拉列表选中项的值和id

    function tijiao(){ var elem = document.getElementById("dish_sort"); var index=elem.selecte ...

  8. RegExp类型和text()方法

    ECMAScript通过RegExp类型来支持正则表达式 RegExp 实例方法:text() 它接受一个字符串参数,在模式与该参数匹配的情况下返回true,否则返回false,通常用在if语句中 / ...

  9. 总结mysql服务器查询慢原因与解决方法

    本文针对MySQL数据库服务器查询逐渐变慢的问题, 进行分析,并提出相应的解决办法,具体的分析解决办法如下: 会经常发现开发人员查一下没用索引的语句或者没有limit n的语句,这些没语句会对数据库造 ...

  10. android模块化app开发-4为APP减负

    现在android应用中一个趋势是应用越来越大,免去游戏不谈普通APP也是一个个的体积直线增长.这里面除了业务增长外各种接口jar包的对接也占了不少比重.像广告SDK,统计SDK,支付SDK等这些我们 ...