基于ABP的模块化、插件化设计,Abp底层框架提供便捷的方法集成每个Module,开发人员可以将自定义的功能以模块的形式集成到ABP中。
模块:

插件:

模块及插件的加载路线:
1. 扩展的HttpApplication对象(在Abp.Web项目中AbpWebApplication<TStartupModule> : HttpApplication)中有AbpBootstrapper成员
AbpWebApplication的Application_Start方法:
protected virtual void Application_Start(object sender, EventArgs e)
{
ThreadCultureSanitizer.Sanitize();
AbpBootstrapper.Initialize();
_webLocalizationConfiguration = AbpBootstrapper.IocManager.Resolve<IAbpWebLocalizationConfiguration>();
}
项目的Global文件中
public class MvcApplication : AbpWebApplication<HKWEBWebModule>
{
protected override void Application_Start(object sender, EventArgs e)
{
AbpBootstrapper.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig("log4net.config")
);
//添加插件
AbpBootstrapper.PlugInSources.AddFolder(@"C:\MyPlugIns");
AbpBootstrapper.PlugInSources.AddTypeList(typeof(MyPlugInModule));
base.Application_Start(sender, e);
}
}
AbpBootstrapper的Initialize方法
public virtual void Initialize()
{
//实例化_logger
ResolveLogger();
try
{
//把Bootstrapper类自身加到容器里
RegisterBootstrapper();
IocManager.IocContainer.Install(new CoreInstaller());
//将附加的插件加入队列
IocManager.Resolve<PlugInManager>().PlugInSources.AddRange(PlugInSources);
//StartupConfiguration.Modules,Settings,ServiceReplaceActions等核心配置
IocManager.Resolve<StartupConfiguration>().Initialize();
_moduleManager = IocManager.Resolve<ModuleManager>();
//加载所有Module
_moduleManager.Initialize(StartupModule);
//对这些Module排序,之后依次执行所有模块的PreInitialize,Initialize,PostInitialize
_moduleManager.StartModules();
}
catch (Exception ex)
{
_logger.Fatal(ex.ToString(), ex);
throw;
}
}
模块管理器的初始化操作会加载所有依赖的模块,并通过模块类型上的Dependon属性确定它们的注册顺序,同时也会加载AbpBootstrapper.PlugInSources中添加的插件,插件的添加 目前提供了两种实现。
AbpBootstrapper的Dispose方法,倒序释放各模块中加载的资源,在AbpWebApplication的Application_End方法中调用。
public virtual void Dispose()
{
if (IsDisposed)
{
return;
}
IsDisposed = true;
//倒序执行所有模块的Shutdown方法
_moduleManager?.ShutdownModules();
}
模块在初始化时往往需要定义一些初始的变量或参数。ABP通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配置中心化。

AbpStartupConfiguration中包含着Setting、Navigation、Location、EventBus、Feature等等核心模块的配置信息的引用,同时提供了一个IModuleConfigurations 类型的成员用于后期模块的扩展。

在AbpBootstrapper的Initialize方法中可以看到它的实例化操作。
利用字典的特性,通过一个扩展方法用于添加配置信息,configurations.AbpConfiguration就是IAbpStartupConfiguration。
public static class AbpWebConfigurationExtensions
{
/// <summary>
/// Used to configure ABP Web module.
/// </summary>
public static IAbpWebModuleConfiguration AbpWeb(this IModuleConfigurations configurations)
{
return configurations.AbpConfiguration.Get<IAbpWebModuleConfiguration>();
}
}
internal class AbpStartupConfiguration : DictionaryBasedConfig, IAbpStartupConfiguration
{
/// <summary>
/// Reference to the IocManager.
/// </summary>
public IIocManager IocManager { get; }
/// <summary>
/// Used to configure modules.
/// Modules can write extension methods to <see cref="ModuleConfigurations"/> to add module specific configurations.
/// </summary>
public IModuleConfigurations Modules { get; private set; }
public T Get<T>()
{
return GetOrCreate(typeof(T).FullName, () => IocManager.Resolve<T>());
}
//……
}
public class DictionaryBasedConfig : IDictionaryBasedConfig
{
/// <summary>
/// Dictionary of custom configuration.
/// </summary>
protected Dictionary<string, object> CustomSettings { get; private set; }
/// <summary>
/// Gets a configuration object with given name.
/// </summary>
public T GetOrCreate<T>(string name, Func<T> creator)
{
var value = Get(name);
if (value == null)
{
value = creator();
Set(name, value);
}
return (T) value;
}
//……
}
每个自定义模块都会提供一个由AbpModule衍生的类型,模块管理器就是遍历所有被应用的程序集,从中找到每一个包含AbpModule类型的视为一个个模块。然后在依据DependsOn对这些Module排序,之后依次执行所有模块的PreInitialize,Initialize,PostInitialize(3个foreach)。
PS:
在AbpModule中有Configurations属性(IAbpStartupConfiguration),以Abp.Web模块为例,在AbpWebModule的PreInitialize中会将本模块的配置信息封装注册到IoC容器,之后通过AbpBootstrapper的Initialize方法中对配置中心的实例化来完成本模块的配置信息的实例化。
通过配置中心在模块初始化时做的事同样也仅仅只是初始化,具体在项目中对这些配置信息的使用则一般是通过各自的管理器来完成,只不过这些管理器都会有对配置中心的引用。
[DependsOn(typeof(AbpWebCommonModule))]
public class AbpWebModule : AbpModule
{
/// <inheritdoc/>
public override void PreInitialize()
{
IocManager.Register<IAbpAntiForgeryWebConfiguration, AbpAntiForgeryWebConfiguration>();
IocManager.Register<IAbpWebLocalizationConfiguration, AbpWebLocalizationConfiguration>();
IocManager.Register<IAbpWebModuleConfiguration, AbpWebModuleConfiguration>();
Configuration.ReplaceService<IPrincipalAccessor, HttpContextPrincipalAccessor>(DependencyLifeStyle.Transient);
Configuration.ReplaceService<IClientInfoProvider, WebAuditInfoProvider>(DependencyLifeStyle.Transient);
AddIgnoredTypes();
}
/// <inheritdoc/>
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
//……
}
原文:http://www.cnblogs.com/wj033/p/6133595.html