国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Ioc容器Autofac系列(1)-- 初窺

2019-11-17 02:03:25
字體:
來源:轉載
供稿:網友

Ioc容器Autofac系列(1)-- 初窺

一.前言

第一次接觸Autofac是因為CMS系統--Orchard,后來在一個開源爬蟲系統--NCrawler中也碰到過,隨著深入了解,我越發覺得Ioc容器是Web開發中必不可少的利器。那么,Ioc容器是用來做什么的?用了有什么好處?我相信如果不明白這兩點就很難敞開心扉接受Ioc容器。

二.傳統解耦設計的弊端

為方便描述,舉個日志的栗子。我簡化實現,一個Log類,一個SaveLog方法。如果其他類想擁有記日志功能,那么只需在內部包含一個Log類型的變量:

 1   public class Log 2    { 3         public void SaveLog(string message) { 4            // save log here. 5        } 6    } 7  8    public class PRoductService { 9        private Log _log;10        public ProductService() {11            _log = newLog();12        }13 14        public void SaveProduct() {15            // save product here.16            //...17            _log.SaveLog("save 1 product");18        }19    }

有經驗的程序員可能會告訴你,這樣做會導致其他類與Log耦合。于是,為了解耦,我們將Log類的功能抽象出來,ILog接口就產生了。如此一來,當其他類需要日志功能時,內含變量就從Log變成了ILog:

 1 public interface ILog { 2          void SaveLog(string message); 3      } 4      public class Log:ILog 5      { 6          public void SaveLog(string message) 7          { 8              // save log here. 9          }10      }11 12      public class ProductService13      {14          private ILog _log;15          public ProductService()16          {17              _log = newLog();18          }19          // .......20      }

由于ILog被抽象出來,它的實現類可多樣化,保存為txt、xml數據庫,甚至可擴展出郵件通知功能等。基本上,我看到的國內項目里,所謂的解耦就只能走到這一步了,但這種設計真的是所謂的“靈活,易擴展,高內聚,低耦合”嗎?

現在,我們來模擬需求變更。假設已有TxtLog類把日志保存成txt文件,但使用一段時間后發現:這種日志難以查詢。項目經理決定將日志保存到數據庫,DbLog類應運而生。但是由于整個系統充斥著new TxtLog(),轉換過程實質上就是逐個查找TxtLog替換成DbLog的過程。此時,項目大小決定出錯率,出錯導致日志記錄不全,記錄不全導致系統故障后查不到日志,查不到日志導致找不到原因,找不到原因導致加班,后果太嚴重了。

忽然有天,高潮降臨,經理或老板決定換回txt或換另外一種日志形式,原因不明,或節省成本,或體驗不好,或佞臣讒言,或成心玩你,或與數據庫有世仇,總之--TMD就是要換。于是,悲劇的查找替換再次上演,幾番折騰,千瘡百孔。

而此時此刻,你還會稱贊這種設計“靈活,易擴展”嗎?

三.邁進IoC大門--改變實例化的方式

現在我們使用Ioc容器--Autofac改進上面的代碼,目標是消除代碼中的new語句,把實例化類的控制權轉移到別的地方,這個地方通常會在一個程序加載時只執行一次的全局方法中。

 1 public class Global { 2      public static IContainer container; 3      public void application_Start() { 4          ContainerBuilder builder=newContainerBuilder(); 5          builder.RegisterType<Log>().As<ILog>(); 6          builder.RegisterType<ProductService>(); 7          container = builder.Build(); 8          var productService = container.Resolve<ProductService>(); 9      }10 }11 12 public class ProductService13 {14      private ILog _log;15      public ProductService(ILog log)16      {17          _log = log;18      }19      // .......20 }

上面代碼中,ContainerBuilder和IContainer是Autofac中的核心類(之后的文章中會介紹,本文不贅述)。當我們要實例化一個ProductService時,需要寫如下代碼:

1 var productService = container.Resolve<ProductService>();

沒有任何跟Log有關的操作,但productService中的_log變量確已被賦值了一個Log的實例。Ioc容器會在已注冊的組件(類或接口)中匹配實例化參數的類型,一旦發現該類型注冊過,則自動將對應的實例賦值給該類型,這個過程叫做--構造函數注入

回頭看看那個曾經折磨過我們的TxtLog換DbLog的問題,托Ioc的福,只要在那個全局方法中改一下類型就解決了。

四.Ioc不僅僅是控制翻轉

也許你會說這個栗子有些極端,實際開發中查找替換的地方并不多,而Ioc只是給實例化換了個地方而已,為了這么一點收益卻要付出巨大的學習成本,是否值得?

實際上,Ioc除了控制反轉外,還提供了很多對實例生命周期的控制,本文使用的Autofac針對流行的框架(如MVC,WCF)提供了簡易整合模塊,以及動態代理功能。在不修改原代碼的前提下,如何為類中方法添加邏輯?Orchard框架通過Autofac和DynamicProxy庫設計出一種很有意思的架構讓兩個不相干的類的方法邏輯能合并在一起。更多細節,我會在之后的系列文章中向大家展示。

五.結語

5月,天降隕星,三斤大菠蘿來襲,我與基友拔劍而起向邪惡宣戰。如今戰罷收心,準備踏實寫一些文章與大家分享,希望這次能堅持久一些^_^。

******************************************************************************

轉載:http://m.survivalescaperooms.com/hkncd/archive/2012/11/21/2780041.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金坛市| 凤山县| 长宁县| 镇赉县| 进贤县| 固始县| 盘山县| 襄垣县| 康定县| 增城市| 克山县| 庄浪县| 额济纳旗| 桐柏县| 郑州市| 湘西| 府谷县| 日土县| 尚义县| 毕节市| 甘德县| 休宁县| 温泉县| 太和县| 德阳市| 辽中县| 永嘉县| 汕尾市| 深州市| 兴宁市| 普宁市| 丰顺县| 新宁县| 武定县| 灵寿县| 从江县| 霍邱县| 高唐县| 饶阳县| 寻甸| 岱山县|