ASP.NET IOC之 AutoFac的認識和結合MVC的使用

   這幾天研究瞭解發現AutoFac是個牛X的IOC容器,是.NET領域比較流行的IOC框架之一,傳說是速度最快的,~ 據相關資料,相關學習,和認知,遂作了一些整理 html

優勢:
它是C#語言聯繫很緊密,也就是說C#裏的不少編程方式均可覺得Autofac使用,例如能夠用Lambda表達式註冊組件
較低的學習曲線,學習它很是的簡單,只要你理解了IoC和DI的概念以及在什麼時候須要使用它們
XML配置支持
自動裝配
與Asp.Net MVC 集成
微軟的Orchad開源程序使用的就是Autofac,從該源碼能夠看出它的方便和強大sql

還有相關介紹:http://www.oschina.net/p/autofac
有博友作了相關測試:http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html
因此牆裂推薦用他做爲IOC的終極解決方案!數據庫

1、AutoFac的簡單使用,第二點介紹在MVC中的使用編程

將Autofac整合到你的應用的基本模式以下:oracle

  • 按照控制反轉(IoC)的思想構建你的應用程序
  • 添加Autofac引用
  • 在application啓動代碼裏建立ContainerBuilder對象
  • 註冊組件
  • Build容器而且保存以備用
  • 在程序執行階段
  • 從容器建立一個做用域
  • 在做用域裏獲取組件的實例

  首先獲取AutoFac,這裏你能夠經過各類方式下載,剛開始我找的各類地址都失效了,有的也沒更新,各類不靠譜,
推薦直接用VS中的NuGet來加載AutoFac,(路徑:工具——NuGet包管理器——管理解決方案的NuGet的程序包——搜索框輸入AutoFac便可,ps搜索框上面得是瀏覽)
不管是哪一種方式,最終的目的就是將 Autofac.dll,Autofac.Configuration.dll 這兩個程序集引用到你的項目中。
這樣在你的項目中,若是想使用AutoFac,只需添加其命名空間引用便可~
app

控制反轉的思想是,在類的構造函數裏傳遞依賴而不是在應用程序裏將這些類綁在一塊兒讓類本身建立他們的依賴。關於依賴注入框架

http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html 這裏有一個很形象的例子。若是感興趣能夠去了解一下。函數

 

一、新建項目,引入DLL或者經過NuGet安裝,而後定義一個數據訪問的接口:工具

// 這個接口幫助咱們從Console 解耦"輸出"方法 
// 咱們不須要關心怎樣輸出,只要知道能輸出便可
public interface IDAL
{
void Insert(string commandText);
}

二、用Sql和Oracle兩種方式分別實現以上接口(僅演示,不是真的實現數據交互)學習

// 這裏IDAL接口的實現完成向控制檯的輸出。
public class SqlDAL : IDAL
{
public void Insert(string commandText)
{
Console.WriteLine("使用sql添加相關信息");
}
}

public class OracleDAL : IDAL
{
public void Insert(string commandText)
{
Console.WriteLine("使用Oracle添加相關信息");
}
}

三、實現構造函數依賴

// DBManager 對上述接口依賴
// 注意這裏的構造函數參數是IDAL 類型 
// 這樣這個Add 的Insert方法由IDAL 的實現決定

public class DBManager 
{ 
  IDAL _dal;
  public DBManager(IDAL dal) 
  { 
   _dal= dal;
  }

public void Add(string commandText) 
 { 
  _dal.Insert(commandText); 
 }
}

 

四、AtuoFac的使用

   說明: 在應用程序啓動過程當中,首先要建立一個ContainerBuilder而且用它註冊你的組件。組件是一個表達式, .NET類型或者其餘的一段暴露一個或者多個服務的代碼而且能夠用在其餘的依賴裏。

簡單來講,就像下面的例子所述,定義一個實現某個接口的.NET類型

 

   public class SomeType : IService
   {
   }

你能夠經過下面兩種方法之一來定位這個類型 
- 指定類型自己,SomeType 
- 指定接口,一個IService

在這個例子裏,這個組件是SomeType,他暴露的服務是SomeTypeIService.

在Autofac裏,你應當用一個ContainerBuilder來註冊他們,以下:

static void Main(string[] args)
{
// 建立你的builder
  var builder = new ContainerBuilder();
  //註冊DBManager,當註冊的類型在相應獲得的容器中能夠Resolve(解析)DBManager實例。
  builder.RegisterType<DBManager>();
  // 註冊類型及其實例。例以下面就是註冊接口IDAL的實例OracleDAL,經過AS可讓DBManager類中經過構造函數依賴注入類型相應的接口。
  builder.RegisterType<OracleDAL>().As<IDAL>(); 
  builder.RegisterType<SqlDAL>().As<IDAL>(); 
  
 // 建立做用域,Build()方法生成一個對應的Container實例使用,而後釋放
  using (var container = builder.Build())
  {
    //經過Resolve解析到註冊的類型實例。
    var manager = container.Resolve<DBManager>();
    manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')");
  }
Console.ReadKey();
}

當你運行你的程序時…

  • Add()方法要求Autofac建立了一個DBManager對象
  • Autofac發現DBManager構造函數須要IDAL
  • Autofac發現IDAL 映射到SqlDAL,因此建立一個新的SqlDAL的實例
  • Autofac使用SqlDAL實例完成IDAL 的建立
  • Autofac返回一個完整的DBManager對象給」Add()」來消費

 

      輸出結果:「使用sql添加相關信息」,

      若是但願輸出不一樣的內容,改變一下注冊過程便可實現控制反轉了

       輸出:"使用Oracle添加相關信息"

 

這是比較簡單的使用方式,若是複雜點,能夠看看這篇
http://www.cnblogs.com/liping13599168/archive/2011/07/16/2108209.html

 


2、AtuoFac AtuoFac在ASP.NET MVC中的應用

一、首先在函數Application_Start() 註冊本身的控制器類,必定要引入Autofac.Integration.Mvc.dll

 1 using System;
 2 using System.Reflection;
 3 using System.Web;
 4 using System.Web.Mvc;
 5 using System.Web.Routing;
 6 using System.Web.Optimization;
 7 using Autofac;
 8 using Autofac.Integration.Mvc;
 9 using AutofacDemo.Models;
10 
11 namespace AutofacDemo
12 {
13 public class MvcApplication : System.Web.HttpApplication
14 {
15   protected void Application_Start()
16   {
17   //依賴注入開始
18   var builder = new ContainerBuilder();
19   builder.RegisterType<StudentRepository>().As<IStudentRepository>();//註冊類型及其實例
20   builder.RegisterControllers(Assembly.GetExecutingAssembly());//註冊當前程序集內全部的Controller類。
21   //// builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();//註冊當前程序集內的全部類
22   var container = builder.Build();
23   DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
24 
25   //MVC用到的
26   AreaRegistration.RegisterAllAreas();
27   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
28   RouteConfig.RegisterRoutes(RouteTable.Routes);
29   BundleConfig.RegisterBundles(BundleTable.Bundles);
30 } 31 } 32 }

 

二、首先聲明一個Student學生類,接口以及實現

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 namespace AutofacDemo.Models
 6 {
 7 public class Student
 8 {
 9 public int Id { get; set; }
10 public string Name { get; set; }
11 public string Graduation { get; set; }
12 public string School { get; set; }
13 public string Major { get; set; }
14 }
15 
16 ///聲明倉儲接口倉儲接口及其實現
17 public interface IStudentRepository
18 {
19 IEnumerable<Student> GetAll();
20 Student Get(int id);
21 Student Add(Student item);
22 bool Update(Student item);
23 bool Delete(int id);
24 }
25 public class StudentRepository : IStudentRepository
26 {
27 private List<Student> Articles = new List<Student>();
28 
29 public StudentRepository()
30 {
31 //添加演示數據
32 Add(new Student { Id = 1, Name = "張三", Major = "軟件工程", Graduation = "2013年", School = "西安工業大學" });
33 Add(new Student { Id = 2, Name = "李四", Major = "計算機科學與技術", Graduation = "2013年", School = "西安工業大學" });
34 Add(new Student { Id = 3, Name = "王五", Major = "自動化", Graduation = "2013年", School = "西安工業大學" });
35 }
36 /// <summary>
37 /// 獲取所有學生信息
38 /// </summary>
39 /// <returns></returns>
40 public IEnumerable<Student> GetAll()
41 {
42 return Articles;
43 }
44 /// <summary>
45 /// 經過ID獲取學生信息
46 /// </summary>
47 /// <param name="id"></param>
48 /// <returns></returns>
49 public Student Get(int id)
50 {
51 return Articles.Find(p => p.Id == id);
52 }
53 /// <summary>
54 /// 添加學生信息
55 /// </summary>
56 /// <param name="item"></param>
57 /// <returns></returns>
58 public Student Add(Student item)
59 {
60 if (item == null)
61 {
62 throw new ArgumentNullException("item");
63 }
64 Articles.Add(item);
65 return item;
66 }
67 /// <summary>
68 /// 更新學生信息
69 /// </summary>
70 /// <param name="item"></param>
71 /// <returns></returns>
72 public bool Update(Student item)
73 {
74 if (item == null)
75 {
76 throw new ArgumentNullException("item");
77 }
78 
79 int index = Articles.FindIndex(p => p.Id == item.Id);
80 if (index == -1)
81 {
82 return false;
83 }
84 Articles.RemoveAt(index);
85 Articles.Add(item);
86 return true;
87 }
88 /// <summary>
89 /// 刪除學生信息
90 /// </summary>
91 /// <param name="id"></param>
92 /// <returns></returns>
93 public bool Delete(int id)
94 {
95 Articles.RemoveAll(p => p.Id == id);
96 return true;
97 }
98 }
99 }

三、添加控制器StudentController,並注入依賴代碼

 1 public class StudentController : Controller
 2 {
 3 readonly IStudentRepository _repository;
 4 
 5 //構造器注入
 6 public StudentController(IStudentRepository repository)
 7 {
 8 this._repository = repository;
 9 }
10 
11 // GET: Student
12 public ActionResult Index()
13 {
14 var data = _repository.GetAll();
15 return View(data);
16 }
17 }

 

四、爲控制器StudentController的Index方法添加視圖

 1 @{
 2 ViewBag.Title = "Index";
 3 }
 4 
 5 <h2>Index</h2>
 6 
 7 @model List<AutofacDemo.Models.Student>
 8 <table id="datatable" cellpadding="0" cellspacing="0">
 9 <thead class="gray_d">
10 <tr>
11 <td class="sth" style="width:3%;">序號</td>
12 <td class="sth" style="width:4%;">姓名</td>
13 <td class="sth" style="width:4%;">專業</td>
14 <td class="sth" style="width:4%;">日期</td>
15 <td class="sth" style="width:4%;">學校</td>
16 </tr>
17 </thead>
18 <tbody>
19 @foreach (var item in Model)
20 {
21 <tr target="sid_user" rel="@Html.DisplayFor(modelItem => item.Id)">
22 <td> @Html.DisplayFor(modelItem => item.Id) </td>
23 <td> @Html.DisplayFor(modelItem => item.Name) </td>
24 <td> @Html.DisplayFor(modelItem => item.Major) </td>
25 <td> @Html.DisplayFor(modelItem => item.Graduation) </td>
26 <td> @Html.DisplayFor(modelItem => item.School) </td>
27 <td>
28 </tr>
29 }
30 </tbody>
31 </table>

 

 

3、關於AutoFac的一些經常使用方法說明

1、builder.RegisterType<Object>().As<Iobject>():
//註冊類型及其實例。例以下面就是註冊接口IDAL的實例SqlDAL ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<SqlDAL>().As<IDAL>(); IContainer container = builder.Build(); SqlDAL sqlDAL = (SqlDAL)container.Resolve<IDAL>(); 2、IContainer.Resolve<IDAL>()://解析某個接口的實例。例如上面的最後一行代碼就是解析IDAL的實例SqlDAL 3、builder.RegisterType<Object>().Named<Iobject>(string name): //爲一個接口註冊不一樣的實例。有時候不免會碰到多個類映射同一個接口, //好比SqlDAL和OracleDAL都實現了IDAL接口,爲了準確獲取想要的類型,就必須在註冊時起名字。
builder.RegisterType<SqlDAL>().Named<IDAL>("sql"); builder.RegisterType<OracleDAL>().Named<IDAL>("oracle"); IContainer container = builder.Build(); SqlDAL sqlDAL = (SqlDAL)container.ResolveNamed<IDAL>("sql"); OracleDAL oracleDAL = (OracleDAL)container.ResolveNamed<IDAL>("oracle"); 4、IContainer.ResolveNamed<IDAL>(string name)://解析某個接口的「命名實例」。例如上面的最後一行代碼就是解析IDAL的命名實例OracleDAL 5、builder.RegisterType<Object>().Keyed<Iobject>(Enum enum)://以枚舉的方式爲一個接口註冊不一樣的實例。
//有時候咱們會將某一個接口的不一樣實現用枚舉來區分,而不是字符串,例如: public enum DBType{ Sql, Oracle} builder.RegisterType<SqlDAL>().Keyed<IDAL>(DBType.Sql); builder.RegisterType<OracleDAL>().Keyed<IDAL>(DBType.Oracle); IContainer container = builder.Build(); SqlDAL sqlDAL = (SqlDAL)container.ResolveKeyed<IDAL>(DBType.Sql); 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時給其賦值 DBManager manager = container.Resolve<DBManager>(new NamedParameter("name", "SQL")); public class DBManager { IDAL dal; public DBManager (string name,IDAL _dal) { Name = name; dal= _dal; }
}
10、經過配置的方式使用AutoFac (使用方式差很少,須要配置,比上面麻煩點,主要優點 例如實現數據庫動態切換,避免程序從新編譯,然並卵,誰沒事換個數據庫玩 先貼上) (1)修改App.config配置文件 必定要注意新建項目 會默認有這個 <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> //不能讓他出如今<configuration> 下第一個節點,否則就報錯, <?xml version="1.0"?> <configuration> <configSections> <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> </configSections> <autofac defaultAssembly="AutofacDemo"> <components> <component type="AutofacDemo.SqlDatabase, AutofacDemo" service="AutofacDemo.IDatabase" /> </components> </autofac> </configuration> 經過Autofac.Configuration.SectionHandler配置節點對組件進行處理。 (2)讀取配置實現依賴注入(注意引入Autofac.Configuration.dll) static void Main(string[] args) { var builder = new ContainerBuilder(); builder.RegisterType<DBManager>(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); using (var container = builder.Build()) { var manager = container.Resolve<DBManager>(); manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')"); } }

 

 

源碼共享地址 : \\10.100.27.47\yebo750\Demo (打開個人電腦輸入便可)

相關文章
相關標籤/搜索