基于DDD的.NET开发框架 - ABP依赖注入
返回ABP系列
ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項(xiàng)目)”的簡(jiǎn)稱。
ASP.NET Boilerplate是一個(gè)用最佳實(shí)踐和流行技術(shù)開(kāi)發(fā)現(xiàn)代WEB應(yīng)用程序的新起點(diǎn),它旨在成為一個(gè)通用的WEB應(yīng)用程序框架和項(xiàng)目模板。
ABP的官方網(wǎng)站:http://www.aspnetboilerplate.com
ABP官方文檔:http://www.aspnetboilerplate.com/Pages/Documents
Github上的開(kāi)源項(xiàng)目:https://github.com/aspnetboilerplate
一、依賴注入概念
控制反轉(zhuǎn)(Inversion of Control,英文縮寫(xiě)為IoC)是一個(gè)重要的面向?qū)ο缶幊痰姆▌t來(lái)削減計(jì)算機(jī)程序的耦合問(wèn)題,也是輕量級(jí)的Spring框架的核心。 控制反轉(zhuǎn)一般分為兩種類型,依賴注入(Dependency Injection,簡(jiǎn)稱DI)和依賴查找(Dependency Lookup)。依賴注入應(yīng)用比較廣泛。
依賴注入是一種軟件設(shè)計(jì)模式的一個(gè)或多個(gè)依賴項(xiàng)注入(或服務(wù)),或通過(guò)引用傳遞,為依賴對(duì)象(或客戶)和客戶端狀態(tài)的一部分。模式之間建立一個(gè)客戶的依賴關(guān)系的行為,它允許程序設(shè)計(jì)是松散耦合的,依賴倒置和單一職責(zé)原則。它直接對(duì)比service locator模式,它允許客戶了解他們所使用的系統(tǒng)找到依賴。
依賴注入不是目的,它是一系列工具和手段,最終的目的是幫助我們開(kāi)發(fā)出松散耦合、可維護(hù)、可測(cè)試的代碼和程序。這條原則的做法是大家熟知的面向接口,或者說(shuō)是面向抽象編程。
理想的軟件開(kāi)發(fā)設(shè)計(jì)是“高內(nèi)聚,低耦合”,高內(nèi)聚側(cè)重面向?qū)ο缶幊?#xff0c;低耦合側(cè)重面向接口編程,控制反轉(zhuǎn)、依賴注入、依賴倒置都蘊(yùn)含著面向接口編程的思想。
控制反轉(zhuǎn)把傳統(tǒng)上由程序代碼直接操控的對(duì)象的調(diào)用權(quán)交給容器,通過(guò)容器來(lái)實(shí)現(xiàn)對(duì)象組件的裝配和管理。所謂的"控制反轉(zhuǎn)"概念就是對(duì)組件對(duì)象控制權(quán)的轉(zhuǎn)移,從程序代碼本身轉(zhuǎn)移到了外部容器。
依賴注入是通過(guò)反射(reflection)動(dòng)態(tài)的向某個(gè)對(duì)象提供它所需要的其他對(duì)象、
常用依賴注入框架:
Unity:微軟patterns&practicest團(tuán)隊(duì)開(kāi)發(fā)的IOC依賴注入框架,支持AOP橫切關(guān)注點(diǎn)。
MEF(Managed Extensibility Framework):是一個(gè)用來(lái)擴(kuò)展.NET應(yīng)用程序的框架,可開(kāi)發(fā)插件系統(tǒng)。
Spring.NET:依賴注入、面向方面編程(AOP)、數(shù)據(jù)訪問(wèn)抽象,、以及ASP.NET集成。
Autofac:最流行的依賴注入和IOC框架,輕量且高性能,對(duì)項(xiàng)目代碼幾乎無(wú)任何侵入性。
PostSharp:實(shí)現(xiàn)靜態(tài)AOP橫切關(guān)注點(diǎn),使用簡(jiǎn)單,功能強(qiáng)大,對(duì)目標(biāo)攔截的方法無(wú)需任何改動(dòng)。
Castle Windsor、StructureMap、Ninject
其實(shí)我感覺(jué)Autofac挺好用的,一直用的Autofac,不知道到Castle Windsor怎么樣。
二、三層和DDD分層依賴關(guān)系
1、三層分層依賴如下圖:
從引用關(guān)系我們就能知道各層的依賴關(guān)系:BLL需要依賴DAL,因?yàn)锽LL中用到了DAL層的實(shí)體。UI這一層需要依賴BLL,還需要依賴DAL,因?yàn)樵赨I中也用到了DAL層實(shí)體。
如果從換個(gè)數(shù)據(jù)庫(kù),DAL需要修改,那DAL的依賴也需要修改。
2、DDD分層依賴關(guān)系圖
從上圖可以知道,表現(xiàn)層和數(shù)據(jù)訪問(wèn)層都依賴領(lǐng)域模型層,這樣的話,如果我們新添加一個(gè)UI界面;更換一種數(shù)據(jù)源的存儲(chǔ)和獲取方式,只需要修改對(duì)應(yīng)層的代碼即可,領(lǐng)域模型層保持了穩(wěn)定。
減少new引入的依賴及緊耦合最好的方式是使用構(gòu)造函數(shù)注入依賴這種設(shè)計(jì)模式:即如果我們需要一個(gè)依賴的實(shí)例,通過(guò)構(gòu)造函數(shù)注入。
解耦和最重要的原則就是依賴倒置原則:
高層模塊不應(yīng)該依賴底層模塊,他們都應(yīng)該依賴抽象。抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。
簡(jiǎn)單理解就是組件應(yīng)該依賴于接口而不是實(shí)現(xiàn)。
三、ABP依賴注入底層實(shí)現(xiàn)
ABP依賴注入是通過(guò)Castle Windsor依賴注入的框架實(shí)現(xiàn)。
1、通過(guò)實(shí)現(xiàn)IConventionalDependencyRegistrar的實(shí)例定義注入的約定,然后通過(guò)IocManager來(lái)讀取這個(gè)規(guī)則完成依賴注入
代碼在Abp項(xiàng)目文件的Dependency文件夾下
?1)在PreInitialize方法中給IocManager的IConventionalDependencyRegistrar的list中加入BasicConventionalRegistrar
IocManager.AddConventionalRegistrar(new BasicConventionalRegistrar());2)IocManager維護(hù)了一個(gè)叫_conventionalRegistrars的list,其中的元素類型就是IConventionalDependencyRegistrar。接著IocManager的RegisterAssemblyByConvention是在模塊的Initialize方法中被調(diào)用
public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }3)IocManager在RegisterAssemblyByConvention方法中遍歷這個(gè)list,并根據(jù)IConventionalDependencyRegistrar的實(shí)例中定義的規(guī)則來(lái)完成register。
/// <summary>/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method./// </summary>/// <param name="assembly">Assembly to register</param>public void RegisterAssemblyByConvention(Assembly assembly){RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());}/// <summary>/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method./// </summary>/// <param name="assembly">Assembly to register</param>/// <param name="config">Additional configuration</param>public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config){var context = new ConventionalRegistrationContext(assembly, this, config);foreach (var registerer in _conventionalRegistrars){registerer.RegisterAssembly(context);}if (config.InstallInstallers){IocContainer.Install(FromAssembly.Instance(assembly));}}?
2、直接使用IocManager的Register方法直接完成注入
AbpModule有個(gè)受保護(hù)的IocManager的成員,所以AbpModule的派生類都可以使用這個(gè)IocManager完成注冊(cè)。
public class AbpWebModule : AbpModule{/// <inheritdoc/>public override void PreInitialize(){if (HttpContext.Current != null){XmlLocalizationSource.RootDirectoryOfApplication = HttpContext.Current.Server.MapPath("~");}//IocManager直接注入IocManager.Register<IAbpWebModuleConfiguration, AbpWebModuleConfiguration>();Configuration.Localization.Sources.Add(new DictionaryBasedLocalizationSource(AbpWebLocalizedMessages.SourceName,new XmlEmbeddedFileLocalizationDictionaryProvider(Assembly.GetExecutingAssembly(), "Abp.Web.Localization.AbpWebXmlSource")));}/// <inheritdoc/>public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }}?
總結(jié)
以上是生活随笔為你收集整理的基于DDD的.NET开发框架 - ABP依赖注入的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 企业内部在centos7.2系统中必杀技
- 下一篇: Java泛型中extends和super
