创建Asp.net MVC并引入Autofac

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

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

autofac实现对Controller的自动注入

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

  1. public class TxtLog:ILog
  2. {
  3. public void Save(string message)
  4. {
  5. //save as txt
  6. }
  7. }

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();
    }

//....

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

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

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

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

  1. protected void Application_Start()
  2. {
  3. ......
  4. ContainerBuilder builder = new ContainerBuilder();
  5. builder.RegisterControllers(Assembly.GetExecutingAssembly());
  6. builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
  7. .AsImplementedInterfaces();
  8. var container = builder.Build();
  9. DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
  10. }

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

autofac应对需求变更

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

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

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

  1. public class DbLog:ILog
  2. {
  3. public void Save(string message)
  4. {
  5. //save to Db.
  6. }
  7. }

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

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

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

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

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

  1. public class HomeController : Controller
  2. {
  3. private ILog _log;
  4. private IEnumerable<ILog> _logList;
  5. public HomeController(ILog log,IEnumerable<ILog> logList )
  6. {
  7. _log = log;
  8. _logList = logList;
  9. }
  10. public ActionResult Index()
  11. {
  12. ViewBag.Message = "Welcome to ASP.NET MVC!";
  13. ViewBag.LogTypeName = _log.GetType().Name;
  14. ViewBag.LogTypeNames = _logList.Select(x => x.GetType().Name).Aggregate((x, y) => x+","+y );
  15. return View();
  16. }

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

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

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

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

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

结语

未完,待续……^_^

源地址:http://www.cnblogs.com/hkncd/archive/2012/11/28/2792474.html

最新文章

  1. Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds
  2. C语言学习 第七次作业总结
  3. jQuery视差滚动插件,(附原理分析,调用方法)
  4. [BZOJ1501][NOI2005] 智慧珠游戏
  5. centos 更新python
  6. 通过rinetd实现端口转发来访问内网的服务
  7. Boostrap(1)
  8. codeforces 478B Random Teams 解题报告
  9. IOS&amp;swift开发常用的网站
  10. Rake::TestTask 介绍
  11. HD1046An Easy Task
  12. 【BZOJ1212】[HNOI2004]L语言 Trie树
  13. freemaker的基本语法
  14. 使用cm-12.0源代码编译twrp
  15. openssh6.7.deb download packed for debian7/ubuntu12.04 amd64
  16. MVVMLight 1:MVVMLight介绍以及在项目中的使用
  17. renren-fast
  18. MyEclipse 2015 Stable 2.0破解方法
  19. Js/Session和Cookies的区别
  20. Trait基础

热门文章

  1. android service 整理
  2. EXTJS4.2 chart 柱状图
  3. linq and rest api in sharepoint
  4. My97DatePicker{js日历插件}
  5. CQRS学习——最小单元的Cqrs(CommandEvent)[其一]
  6. python读取mnist
  7. spoj 62
  8. cf 283A
  9. 如何助力企业 APP 在竞争中占据先机?
  10. 深入理解计算机各种类型大小(sizeof)