草庐IT

ABP之依赖注入源码解析

语梦·添香 2023-03-28 原文

ABP的依赖注入基于Castle Windsor,可以通过Nuget搜索Castle.Windsor来安装使用

 

 

 ABP框架运行其实是以模块进行加载的运行的,通过源码得知AbpModule是所有模块基类(也就是说一个程序集就是一个模块,我们在创建类库时,可以在创建一个模块类的时候继承AbpModule),本质上是一个抽象类,有三个虚方法,分别为:PreInitialize、Initialize、PostInitialize.

 

子类在继承的时候,必须重写它,在PreInitialize方法里就可以通过Castle Windsor依赖注入接口对象:

 

图中,可以看到,通过IcoManager.AddConventionalRegister方法按照约定注册了mvc的控制器,这些都是ABP在启动的时候,自行注入。

 

ABP中的依赖注入

1、注册(Registering

在ABP中,有很多种方式来注册你的类到到系统里,通常常规方法就可以满足我们大部分日常场景。

2、常规注册(conventional registration

在ABP中大量运用到【常规注册】,按照约定ABP在启动的时候会自动注入IRepository、IDomainService、IApplicationService、ILogger、MVC控制器、webapi控制器。

比如:mvc控制器。

 

从图中可以看到,通过IcoManager.AddConventionalRegister方法,传入了ControllerConventionalRegistrar实例,F12进入其中,可看到

 

 当然比较有意思的是下图中的红线框框处的代码:

 解释下:这是以WindsorControllerFactory取代了asp.net mvc默认的控制器工厂,并且注入我们的IOC容器实例,这样我们即可在控制器的构造函数中通过依赖注入,获取接口对象实例。

那问题来了,这些常规注册的对象,是如何在应用在启动的时候就注入到了ioc容器了呢?答案看下图:

AbpWebApplication类相当与Global.asax文件(asp.net的开发不陌生吧)

 

 

 我们再细看AbpBootstrapper的Initialize方法:

 

 

ABP的依赖注入几个核心接口

 IApplicationService

比如,你可能有一个IPersonAppService接口和一个实现了该接口的PersonAppService类:

public interface IPersonAppService : IApplicationService
{
    //...
}

public class PersonAppService : IPersonAppService
{
    //...
}

因为它实现了IApplicationService接口(只是一个空接口),所以ABP会自动注册它,并注册为transient(每次使用创建一个实例)。当你使用构造函数注入IPersonAppService接口到一个类中时,一个PersonAppService对象会自动地创建并传入该类的构造函数中。

命名规范在ABP中非常重要。比如,你可以将PersonAppService更名为MyPersonAppService或是其他包含了“PersonAppService”后缀的名字,因为IPersonAppService接口有这个后缀。但你不能将它命名为PeopleService。如果你没有按照这种命名规范来操作的话,那么IPersonAppService不会自动地注册(但是它已经以自注册的方式注入到DI框架,而不是接口方式),因此如果你想要以接口方式注册的话,那么你应该手动注册。

IDomainService

ABP定义了IDomainService接口,所有的领域服务都按照惯例实现了该接口。当实现时,领域服务会以transient自动注册到依赖注入系统。

此外,领域服务(可选地)可以从DomainService类继承。因此,它可以使用一些继承的属性,比如logging,本地化等等。当然,如果没有继承,如果需要的话也可以注入这些属性。

 

ITransientDependency

事务依赖 ,在ABP的核心模块AbpKernelModule中按照约定注册:如图

 

ITransientDependency

 

有关ABP之依赖注入源码解析的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  4. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  7. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  8. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  9. ruby - 这个 ruby​​ 注入(inject)魔术是如何工作的? - 2

    我今天看到了一个ruby​​代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem

  10. ruby - 如何使用 Nokogiri 解析纯 HTML 表格? - 2

    我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315

随机推荐