[TOC] 說說ABP的依賴註入 上篇 "abp運行機制分析" 分析了ABP在啟動時,都做了那些事;這篇我們來說說ABP的最核心的一部分:依賴註入(DependencyInjection),以下簡稱DI; DI的概念我就不說了,關鍵字出來的資料非常多了,這裡就不說了,這裡主要討論的是ABP是如何做到 ...
[TOC]
說說ABP的依賴註入
上篇abp運行機制分析分析了ABP在啟動時,都做了那些事;這篇我們來說說ABP的最核心的一部分:依賴註入(DependencyInjection),以下簡稱DI;
DI的概念我就不說了,關鍵字出來的資料非常多了,這裡就不說了,這裡主要討論的是ABP是如何做到自依賴註入的(self register)
讀過ABP的依賴註入文檔內容我們知道:當你想註入一個服務時,最佳實踐是根據命名規範(Naming conventions)來命名,也就是說,加入你想註入一個叫IPersonAppService的服務類,那麼你的實現介面的服務類就應該按照Naming conventions規則命名為PersonAppService或者是保留“PersonAppService”字樣,改成"Profix+PersonAppService"就能實現self register;否則的話就只能通過另寫代碼顯示的註冊介面與實現類;
其實這不是ABP框架這麼要求的,這是ABP附帶的DI組件——Castle Windsor這麼要求的;讓我們來看看ABP框架的代碼就知道了
代碼追蹤
閱讀過ABP文檔的人應該知道,自依賴註入的關鍵入口是你項目的WebApplication.Module類的初始化方法Initialize
下的IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
顧名思義,就是註冊當前運行程式集所有按照命名規範的實現介面類;我們來看看IocManager
屬性,F12我們知道這是一個介面類IIocManager
,繼續追蹤可以看出IIocManager
繼承兩個介面,一個是Ioc註冊介面IIocRegistrar
和Ioc解析介面IIocResolver
並且之前提到的Naming conventions以及abp運行機制分析知道IocManager就是IIocManager的實現類:
public interface IIocManager : IIocRegistrar, IIocResolver, IDisposable
{
IWindsorContainer IocContainer { get; }
new bool IsRegistered(Type type);
new bool IsRegistered<T>();
}
public class IocManager : IIocManager, IIocRegistrar, IIocResolver, IDisposable
{
.../
public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config);
public void RegisterAssemblyByConvention(Assembly assembly);
.../
}
public void RegisterAssemblyByConvention(Assembly assembly)
內部調用了它的另一個重載函數RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
並傳一個預設規範註冊選項配置,而這裡配置類就僅僅只是設置一個是否自動按照命名規範註冊介面實現類標識InstallInstallers
,接著初始化ConventionalRegistrationContext
上下文,然後遍歷預設的規約註冊器組註冊去註冊各種服務,最後根據InstallInstallers
來判斷是否調用self-register
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)
{
//這裡這句話就是Castle Windsor在做的事,也就是按照命名規範實現自動註冊服務關鍵所在
IocContainer.Install(FromAssembly.Instance(assembly));
}
}
上面這段代碼有點要註意,就是foreach段,這裡遍歷一個註冊器集合;這是在IocManager初始化時候就會初始化一個空的IConventionalDependencyRegistrar
集合,然後在應用程式啟動載入Module時就會增加一個預設實現類基礎註冊器BasicConventionalRegistrar
,裡面包含三種註冊服務的細節——Transient,Singleton,Windsor Interceptors;
註入BasicConventionalRegistrar
細節源代碼如下:
public sealed class AbpKernelModule : AbpModule
{
public override void PreInitialize()
{
IocManager.AddConventionalRegistrar(new BasicConventionalRegistrar());
IocManager.Register<IScopedIocResolver, ScopedIocResolver>(DependencyLifeStyle.Transient);
IocManager.Register(typeof(IAmbientScopeProvider<>), typeof(DataContextAmbientScopeProvider<>), DependencyLifeStyle.Transient);
AddAuditingSelectors();
AddLocalizationSources();
AddSettingProviders();
AddUnitOfWorkFilters();
ConfigureCaches();
AddIgnoredTypes();
}
}
看到這裡我相信ABP的依賴註入很清晰了;
下篇我們來說說ABP的緩存管理以及如何寫自定義緩存管理類,學習下別人的框架是如何封裝的,如何做到高可用,拓展性強的框架的