Asp.net MVC 使用Autofac的簡單使用 IOC


  Ioc(Inversion of Control)或者叫依賴注入DI(Dependency Injection)
  如果一個接口有兩個實現類,但是在實現過程中,用到了這兩個具體的實現類。
  如果采用IOC,則只能是注冊一個接口類型,那么如何確保IOC在合適的時候傳入不同類的實例?這是我突然間想到的一個問題,希望園友們可以幫忙解答一下!

 

  所謂IOC(控制反轉)或者說是依賴注入,就是將你設計好的類交給系統去控制,而不是在你的類內部控制,控制權發生了變化,就稱為控制反轉。
 
  IOC的使用時機就是在一個接口有多個實現類的情況下,並且還可能存在擴展這個接口的可能性的情況下使用我個人覺得是最好的。
 
  我們使用抽象接口來隔離使用者和具體實現類之間的依賴?誰依賴誰呢?我們要清楚的明白這個關系才能更好的明白如何使用IOC。我以為是使用者依賴具體的實現。
  IOC表示的是依賴注入,但是這個表示誰依賴誰呢?
 
Class A
{
IB _b;
public A()
{
_b=new ImpB();//在調用實現類的ImpB中方法  定義一個該類型的變量  采用接口定義方式  ,這個采用接口定義的方式,可以用來叫做面向接口的編程,這個在現在也是一種很常用的方式。不采用面向抽象編程而是采用面向接口編程。
}
}
 
Class ImpB:IB
{
//具體的實現類
}
class ImpC:IB
{
//C具體的實現
}
但是如果采用IOC方式,只需要在A的構造函數中傳入必須的參數。這就會出現上面我提到的兩個實現類的問題。
還有我還要提出一個問題,一個實現類繼承自兩個接口,那么如何進行值的注入呢?
 
 
關於IOC的幾個概念:
 
服務:     組件       自動裝配
 
所謂服務,就是一系列的接口,接口約定了服務,從而使隨意的更換實現接口的具體實現不會對使用該服務的代碼進行任何的更改。面向服務的編程   ==面向接口的編程?
 
組件:組件是一個可重用的程序單元,是實現了某個具體接口並且僅僅實現了該接口的實現類。組件是實現了某個服務接口的類。
具體的實現類。
 
自動裝配(Auto Wiring):指的是由容器自動管理組件之間的依賴關系。自動在需要具體實現的時候通過某種注入方式注入需要的實例。
 
IOc也屬於一種設計模式,它主要是用來協調各個組件之間的組合關系。增加了程序的可遷移性以及良好的組件解耦。不需要在實現類中使用new 來實例化對象,避免了組件類之間的耦合,也避免了在需要更改具體時候的時候更改程序的內部代碼實現。
 
IOC很好的解決了這個問題,它把組件之間的關系由程序內部提到外部容器來管理,也就是說由容器在運行期間將組件間的依賴關系動態的注入組件中。
控制程序間關系的實現交給了外部容器來管理,這就是所謂的好萊塢法則。不要找我,我會找你。
 
下面還有一個要注意的就是關注點分類(SOC),這應該算是IOC的最初的目的,實現關注點的分離,通過分解程序,把程序分解成一個個的功能點,然后確保每個功能點都是沒有相互直接聯系的。這就是關注點分離原則。在IOC將控制權轉移到自己手上的時候其實就是就是解除了組件之間的實際依賴關系,解除了組件(也就是實現類)直接的直接耦合。實現了基本的關注點分離原則。
 
還有一個設計原則叫做面向切面的編程原則(AOP),這種方式是縱向的看待程序功能。
 
我個人認為IOC是一個理論,這DI則是具體實現方式,
 
現在我來提一個問題?為什么我們必須要在application_start方法中注冊autofac或ioc,以便進行組件解耦?
 
答:我們知道無論是asp.net web form還是MVC,最終都是運行在.Net framework 之上,通過IIS控制從頁面請求到頁面響應的整個過程。每個請求從進入到最后響應(暫且稱為聲明周期)都是被asp.net 工作者進程把持,因為我們無法直接的控制該進程,所以我們想在整個生命周期內進行注入的可能性基本上就不存在。既然這樣,我們就只能是在生命周期開始之前就進行注入。在一個請求從進入到響應會經過IIS的很多處理,其中IhttpModule 管線就可以被我們使用來進行依賴注入。這也就解釋了為什么我們只能在程序啟動之前注冊。
 
 
 
Autofac是在IOC理論下和C#緊密結合的一個框架,它提供了相對其他框架所不可比擬的優勢:
 
1.使用C#泛型
2.可以方便的注冊Asp.net MVC Controller
3.支持C# lambda表達式,以及對linq的完美支持
4.具有無侵入性,可以在運行時對對象的實例以及聲明周期進行管理
5.輕量級的框架
 
Autofac的簡單使用:
1.注冊類型的簡單,無需任何xml配置就可以使autofac正常運行。當然autofac也可以通過xml配置文件進行配置。
 
public void ApplicationStart()
  {
var builder=new ContainerBuilder();//創建autofac管理注冊類的容器實例
//下面就需要為這個容器注冊它可以管理的類型
//builder.Register... builder的register方法可以通過多種方式注冊類型
//其實register這些方法我們有必要詳細的了解一下,畢竟每種方法都可以找到針對的使用地方
 
//builder.Build();//生成具體的實例
 
//下面就是使用MVC的擴展 更改注入方式
 
            var container=builder.Build();
            DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));//更改了MVC中的注入方式
2.在homeController中使用構造函數注入
public class HomeController
{
private Inet _net;
public HomeController(Inet net)//接口定義  構造函數注入
{
_net=net;  //我們在運行時通過單步調試就可以看到net其實就是我們實現接口Inet的具體實例。前提是已經正確注冊了autofac並且正確的進行配置
}
public ActionResult()
{
var result=_net.GetAll();//調用具體類的具體方法返回結果
return view(result); //進行值的傳遞
}
}
 這樣我們就可以在項目中使用autofac作為組件來管理我們的程序,進行控制權的轉移。
 
總結一下,IOC本質上就是使用戶的控制權轉移到單獨的組件上(autofac),通過各種方式的注入來達到組件之間的解耦,實現關注點分離的效果。
autofac的使用非常簡單,我就不再舉例說明,我只是說明了IOC的使用背景。
 
我沒有看過autofac的源代碼,不知道我的認識是不是正確,如果有錯誤,請你指出來,我會積極改正,謝謝。
 
還有IOC只是一種手段,不是目的,不是我們設計架構時應該考慮的事情,這只是我們在實現時采用的技巧,當然也有其他方法可以達到類似的效果,也有很多這樣的組件可以達到這個效果。我們的最終目的是實現關注點的分離以及組件之間的耦合度最低。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM