NopCommerce架構(gòu)分析(一)Autofac依賴(lài)注入類(lèi)生成容器
NopCommerce為了實(shí)現(xiàn)松耦合的框架設(shè)計(jì)目的,使用了IOC框架:Autofac。據(jù)有人測(cè)試,Autofac是性能很好的IOC工具。
1、在IOC中,組件首先需要在IOC中注冊(cè),有通過(guò)配置文件注冊(cè)的。像Spring.net,也有通過(guò)特性注冊(cè)的,像StructureMap,也有通過(guò)代理來(lái)注冊(cè)的,像Autofac。但是IOC講究一個(gè)原則,就是接口和實(shí)現(xiàn)分離。所有IOC就是生命某個(gè)具體類(lèi)實(shí)現(xiàn)了某個(gè)接口。然后在使用時(shí),系統(tǒng)從IOC中獲取接口的實(shí)現(xiàn)類(lèi),并創(chuàng)建對(duì)象。
2、下面來(lái)看NopCommerce如何使用Autofac實(shí)現(xiàn)松耦合的框架設(shè)計(jì)的。其實(shí)它的插件機(jī)制也是通過(guò)Autofac來(lái)實(shí)現(xiàn)的。
IOC的封裝及靈活使用機(jī)制主要在Nop.Core.Infrastructure中封裝的。在Autofac中,對(duì)象又稱(chēng)為組件。組件生命周期分為:?jiǎn)卫?、臨時(shí)和生命周期域內(nèi),如下定義:
namespace Nop.Core.Infrastructure.DependencyManagement { public enum ComponentLifeStyle { Singleton = 0, Transient = 1, LifetimeScope = 2 } }
Autofac中有容器、并提供方法注冊(cè)接口及其類(lèi)型,還提供方法查找到注冊(cè)的類(lèi)型,以及自動(dòng)創(chuàng)建對(duì)象。
3、類(lèi)型查找器
為了支持插件功能,以及支持一些自動(dòng)注冊(cè)的功能。系統(tǒng)提供了類(lèi)型查找器。ITypeFinder以及實(shí)現(xiàn)類(lèi)就是提供此功能。通過(guò)類(lèi)型查找器可以查找本程序域中的類(lèi),也可以查找整個(gè)bin目錄下所有動(dòng)態(tài)鏈接庫(kù)中類(lèi),并把它們注冊(cè)到類(lèi)型反轉(zhuǎn)容器中。ITypeFinder以及實(shí)現(xiàn)類(lèi)如下:
4、類(lèi)型注冊(cè)
容器管理類(lèi):ContainerManager,管理通過(guò)Autofac生成的容器;
容器配置器:ContainerConfigurer:配置依賴(lài)反轉(zhuǎn)容器,建立整個(gè)框架的類(lèi)型依賴(lài)注冊(cè)和類(lèi)型查找類(lèi)之間的關(guān)系。
在系統(tǒng)中有一個(gè)依賴(lài)類(lèi)引擎上下文環(huán)境:EngineContext,可以根據(jù)配置文件生成引擎,此引擎是負(fù)責(zé)根據(jù)類(lèi)型接口從容器中返回對(duì)象。
系統(tǒng)默認(rèn)引擎NopEngine,若沒(méi)有配置有效的引擎,即用默認(rèn)引擎,生成的引擎保存在單例容器中。
它們的關(guān)系如下:
系統(tǒng)在類(lèi)MvcApplication的方法Application_Start中初始化引擎上下文。并通過(guò)調(diào)用EngineContext.Initialize(false);實(shí)現(xiàn)所有反轉(zhuǎn)依賴(lài)的注冊(cè)功能;
5、容器注冊(cè)類(lèi)
系統(tǒng)注冊(cè)接口為:IDependencyRegistrar,系統(tǒng)通過(guò)ContainerConfigurer注冊(cè)此接口以及實(shí)現(xiàn)類(lèi)的,并通過(guò)ITypeFinder類(lèi)搜尋程序集里實(shí)現(xiàn)接口IDependencyRegistrar的類(lèi)。代碼如下:
namespace Nop.Core.Infrastructure.DependencyManagement { /// <summary> /// Configures the inversion of control container with services used by Nop. /// </summary> public class ContainerConfigurer { public virtual void Configure(IEngine engine, ContainerManager containerManager, EventBroker broker, NopConfig configuration) { //other dependencies containerManager.AddComponentInstance<NopConfig>(configuration, "nop.configuration"); containerManager.AddComponentInstance<IEngine>(engine, "nop.engine"); containerManager.AddComponentInstance<ContainerConfigurer>(this, "nop.containerConfigurer"); //type finder containerManager.AddComponent<ITypeFinder, WebAppTypeFinder>("nop.typeFinder"); //register dependencies provided by other assemblies var typeFinder = containerManager.Resolve<ITypeFinder>(); containerManager.UpdateContainer(x => { var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>(); var drInstances = new List<IDependencyRegistrar>(); foreach (var drType in drTypes) drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType)); //sort drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList(); foreach (var dependencyRegistrar in drInstances) dependencyRegistrar.Register(x, typeFinder); }); //event broker containerManager.AddComponentInstance(broker); } } }
而接口IDependencyRegistrar的內(nèi)容如下:
namespace Nop.Core.Infrastructure.DependencyManagement { public interface IDependencyRegistrar { /// <summary> /// 此方法在通過(guò)ContainerBuilder注冊(cè)依賴(lài)關(guān)系。 /// </summary> /// <param name="builder">容器管理者類(lèi)</param> /// <param name="typeFinder">類(lèi)型查找者接口</param> void Register(ContainerBuilder builder, ITypeFinder typeFinder); /// <summary> /// 注冊(cè)排序序號(hào) /// </summary> int Order { get; } } }
6、單例類(lèi)容器
單例類(lèi)系列保存系統(tǒng)中與程序相同生命周期的單例對(duì)象,或者叫做單例類(lèi)容器。
其中包括實(shí)體類(lèi),集合類(lèi)和字典類(lèi)的單例容器。
Singleton<T>,SingletonList<T>,SingletonDictionary<TKey, TValue>。EngineContext就是通過(guò)Singleton<T>類(lèi)來(lái)管理引擎的。
7、MVC 服務(wù)提供類(lèi)。
類(lèi)型依賴(lài)獲取器:NopDependencyResolver,通過(guò)繼承mvc下的接口:IDependencyResolver,并在Application_Start方法中注冊(cè),使之在系統(tǒng)啟動(dòng)時(shí)調(diào)用。
//set dependency resolver var dependencyResolver = new NopDependencyResolver(); DependencyResolver.SetResolver(dependencyResolver);
8、其他
事件攔截類(lèi):EventBroker:過(guò)濾向系統(tǒng)發(fā)送的請(qǐng)求,防止由于臨時(shí)的錯(cuò)誤或異常導(dǎo)致系統(tǒng)崩潰。
系統(tǒng)啟動(dòng)時(shí)執(zhí)行任務(wù):IStartupTask,啟動(dòng)時(shí)執(zhí)行的任務(wù)主要是數(shù)據(jù)庫(kù)的初始化和加載。
- NopCommerce架構(gòu)分析之(八)多語(yǔ)言支持
- NopCommerce架構(gòu)分析之(七)主題Theme皮膚管理器
- NopCommerce架構(gòu)分析之(六)自定義RazorViewEngine和WebViewPage
- NopCommerce架構(gòu)分析之(五)Model綁定Action參數(shù)
- NopCommerce架構(gòu)分析之(四)基于路由實(shí)現(xiàn)靈活的插件機(jī)制
- NopCommerce架構(gòu)分析之(三)EntityFramework數(shù)據(jù)庫(kù)初試化及數(shù)據(jù)操作
- 使用Nopcommerce為商城添加滿XX減XX優(yōu)惠券功能
- 基于nopCommerce的開(kāi)發(fā)框架 附源碼
相關(guān)文章
在ASP.NET 2.0中操作數(shù)據(jù)之二十七:創(chuàng)建自定義排序用戶界面
本文主要講解ASP.NET 2.0中使用GridView創(chuàng)建自定義排序,主要演示在一組相同類(lèi)別的數(shù)據(jù)前添加分界行,讓用戶更容易區(qū)分不同組的數(shù)據(jù)。2016-05-05ASP.NET MVC4入門(mén)教程(五):從控制器訪問(wèn)數(shù)據(jù)模型
本文介紹ASP.NET MVC4中在創(chuàng)建控制器的時(shí)候,同時(shí)使用Entity Framework為模型生成增刪改查等方法,方便控制器調(diào)用。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之十六:概述插入、更新和刪除數(shù)據(jù)
本文主要介紹ASP.NET中插入、更新和刪除數(shù)據(jù)的原理,ObjectDataSource在頁(yè)面和潛在的數(shù)據(jù)之間扮演一個(gè)代理的角色,配合業(yè)務(wù)邏輯可以執(zhí)行Select()、Insert()、Update()和Delete()方法。2016-05-05《解剖PetShop》之五:PetShop之業(yè)務(wù)邏輯層設(shè)計(jì)
業(yè)務(wù)邏輯層(Business Logic Layer)無(wú)疑是系統(tǒng)架構(gòu)中體現(xiàn)核心價(jià)值的部分,本文主要講解PetShop4.0的業(yè)務(wù)邏輯層設(shè)計(jì),需要的朋友可以參考下。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之十八:在ASP.NET頁(yè)面中處理BLL/DAL層的異常
本文主要介紹ASP.NET 2.0中如何在頁(yè)面中處理BLL和DAL層的異常,程序演示了如何在頁(yè)面中顯示友好的異常信息,以及講解了如何在DAL層拋出自定義異常。2016-05-05NopCommerce架構(gòu)分析之(六)自定義RazorViewEngine和WebViewPage
本文對(duì)NopCommerce的后臺(tái)分離技術(shù)做簡(jiǎn)單的探討。NopCommerce通過(guò)自定義視圖引擎,重寫(xiě)了VirtualPathProviderViewEngine類(lèi)的CreateView、CreatePartialView、FindView、FindPartialView方法,添加自定義的視圖搜索路徑來(lái)實(shí)現(xiàn)后臺(tái)分離。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之六十七:在TableAdapters中使用JOINs
使用TableAdapter向?qū)в幸欢ǖ木窒扌?,只能?chuàng)建出不含JOIN的存儲(chǔ)過(guò)程,那么本文就為大家講解,如何在TableAdapters中使用包含JOIN的存儲(chǔ)過(guò)程。2016-05-05