abp 模块化
IAbpModuleDescriptor
模块描述符用来加载模块的,因为模块的依赖在代码里只是表示关系,那这种关系需要描述出来,在 实际运行的时候依据描述进行模块的实例化到 IOC 里
namespace Volo.Abp.Modularity;
public interface IAbpModuleDescriptor
{
Type Type { get; }
Assembly Assembly { get; }
//实例化后的模块
IAbpModule Instance { get; }
//通过加载 dll 的插件模块
bool IsLoadedAsPlugIn { get; }
IReadOnlyList<IAbpModuleDescriptor> Dependencies { get; }
}
AbpModuleDescriptor 实现类 主要就是构造函数实现以上的只读属性
IModuleContainer
IModuleContainer 所有加载的模块统一的读取接口
public interface IModuleContainer
{
[NotNull]
IReadOnlyList<IAbpModuleDescriptor> Modules { get; }
}
IAbpModule
IAbpModule 模块的定义,模块在运行起来的时候具有功能
模块主功能就是给 IOC 容器增加服务,此服务就是模块自己可以使用的服务,模块背后代表的意思就 是注册的一堆模块相关的服务
public interface IAbpModule
{
Task ConfigureServicesAsync(ServiceConfigurationContext context);
void ConfigureServices(ServiceConfigurationContext context);
}
ServiceConfigurationContext
通过 ServiceConfigurationContext 配置上下文,之所以有这个接口主要目的还是为了封装 Items,这 个上下文在把模块的服务注入进来的时候会使用它
public class ServiceConfigurationContext
{
public IServiceCollection Services { get; }
// the service registration phase and shared between modules.
// 在服务注册阶段,在模块之间传递的共享信息
public IDictionary<string, object?> Items { get; }
public object? this[string key] {
get => Items.GetOrDefault(key);
set => Items[key] = value;
}
public ServiceConfigurationContext([NotNull] IServiceCollection services)
{
Services = Check.NotNull(services, nameof(services));
Items = new Dictionary<string, object?>();
}
}
AbpModule
IAbpModule 实现者 AbpModule ,这是一个抽象类,实现了一些模块的生命周期接口,不过都是虚 实现,生命周期的具体执行内容还是有用户自己实现模块的生命周期是随着 Application 执行的,所以 实现的是 Application 的生命周期接口
伴随者应用程序启动及关闭发生的生命周期每个模块都可以参与其中,前三类生命周期是人为划分的, 应用程序本身只有 OnApplicationInitialization,人为的在启动的前后加入 pre 和 post 的生命周 期
- IOnPreApplicationInitialization,
- IOnApplicationInitialization,
- IOnPostApplicationInitialization,
- IOnApplicationShutdown,
public abstract class AbpModule :
IAbpModule,
IOnPreApplicationInitialization,
IOnApplicationInitialization,
IOnPostApplicationInitialization,
IOnApplicationShutdown,
IPreConfigureServices,
IPostConfigureServices
{
// 模块一些默认的服务可以自动注入进来,这里指定是否不用自动注入
protected internal bool SkipAutoServiceRegistration { get; protected set; }
protected internal ServiceConfigurationContext ServiceConfigurationContext {
get {
if (_serviceConfigurationContext == null)
{
throw new AbpException($"{nameof(ServiceConfigurationContext)}
is only available in the {nameof(ConfigureServices)},
{nameof(PreConfigureServices)} and {nameof(PostConfigureServices)} methods.");
}
return _serviceConfigurationContext;
}
internal set => _serviceConfigurationContext = value;
}
private ServiceConfigurationContext? _serviceConfigurationContext;
/** 配置服务 */
public virtual Task PreConfigureServicesAsync(ServiceConfigurationContext context)
{
PreConfigureServices(context);
return Task.CompletedTask;
}
public virtual void PreConfigureServices(ServiceConfigurationContext context)
{
}
public virtual Task ConfigureServicesAsync(ServiceConfigurationContext context)
{
ConfigureServices(context);
return Task.CompletedTask;
}
public virtual void ConfigureServices(ServiceConfigurationContext context)
{
}
public virtual Task PostConfigureServicesAsync(ServiceConfigurationContext context)
{
PostConfigureServices(context);
return Task.CompletedTask;
}
public virtual void PostConfigureServices(ServiceConfigurationContext context)
{
}
/** 生命周期的接口方法都是虚方法,省略不写 */
// 判断一个类型是否是一个 AbpModule 的静态方法
public static bool IsAbpModule(Type type)
{
var typeInfo = type.GetTypeInfo();
return
typeInfo.IsClass &&
!typeInfo.IsAbstract &&
!typeInfo.IsGenericType &&
typeof(IAbpModule).GetTypeInfo().IsAssignableFrom(type);
}
internal static void CheckAbpModuleType(Type moduleType)
{
if (!IsAbpModule(moduleType))
{
throw new ArgumentException("Given type is not an ABP module: " +
moduleType.AssemblyQualifiedName);
}
}
/** 和配置相关的,因为配置也是作为依赖注入的 单例注入IOC, 模块自己的配置也是按照模块隔离的,
配置的方法也是使用微软配置相关的接口,也可以通过 IServiceCollection 去配置
*/
//把固定的值配置给一个对象 TOptions, 在内部 使用 ServiceConfigurationContext.Services
//.Configure(name, configureOptions);
protected void Configure<TOptions>(string name, Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure(name, configureOptions);
}
//给配置对象起个 key
protected void Configure<TOptions>(string name, Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure(name, configureOptions);
}
// 直接提供一个 配置对象
protected void Configure<TOptions>(IConfiguration configuration)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure<TOptions>(configuration);
}
/** 模块自己提供的预配置方法,在模块启依赖服务注册前就先执行的配置,没有感觉到有特别的用处 */
protected void PreConfigure<TOptions>(Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.PreConfigure(configureOptions);
}
/** asp.net core 原来的配置方法,在模块启依赖服务注册后执行的配置 PostConfigureAll
是同时覆盖命名和缺省配置 */
protected void PostConfigure<TOptions>(Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.PostConfigure(configureOptions);
}
protected void PostConfigureAll<TOptions>(Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.PostConfigureAll(configureOptions);
}
}
IModuleLifecycleContributor 模块的生命周期贡献器
模块的生命周期 IModuleLifecycleContributor 模块生命周期本身只有俩种大类(Application 本身只要俩种) InitializeAsync , ShutdownAsync. 它的实现类 ModuleLifecycleContributorBase
public abstract class ModuleLifecycleContributorBase : IModuleLifecycleContributor 定义 的是虚方法
public interface IModuleLifecycleContributor : ITransientDependency
{
Task InitializeAsync(
[NotNull] ApplicationInitializationContext context, [NotNull] IAbpModule module);
void Initialize(
[NotNull] ApplicationInitializationContext context, [NotNull] IAbpModule module);
Task ShutdownAsync(
[NotNull] ApplicationShutdownContext context, [NotNull] IAbpModule module);
void Shutdown(
[NotNull] ApplicationShutdownContext context, [NotNull] IAbpModule module);
}
public abstract class ModuleLifecycleContributorBase : IModuleLifecycleContributor
{
public virtual Task
InitializeAsync(ApplicationInitializationContext context, IAbpModule module)
{
return Task.CompletedTask;
}
public virtual void
Initialize(ApplicationInitializationContext context, IAbpModule module)
{
}
public virtual Task
ShutdownAsync(ApplicationShutdownContext context, IAbpModule module)
{
return Task.CompletedTask;
}
public virtual void
Shutdown(ApplicationShutdownContext context, IAbpModule module)
{
}
}
ModuleLifecycleContributorBase 实现类是如下四个方法,内部都是调用 AbpModule 里用户定义的生 命周期方法
- OnApplicationInitializationModuleLifecycleContributor
- OnApplicationShutdownModuleLifecycleContributor
- OnPreApplicationInitializationModuleLifecycleContributor 也是实现 ModuleLifecycleContributorBase 的 Initialize 方法
- OnPostApplicationInitializationModuleLifecycleContributor 也是实现 ModuleLifecycleContributorBase 的 Initialize 方法
IModuleLifecycleContributor 的四个实现类
public class OnApplicationInitializationModuleLifecycleContributor
: ModuleLifecycleContributorBase
{
public async override Task InitializeAsync(
ApplicationInitializationContext context, IAbpModule module)
{
if (module is IOnApplicationInitialization onApplicationInitialization)
{
await onApplicationInitialization.
OnApplicationInitializationAsync(context);
}
}
public override void Initialize(ApplicationInitializationContext context, IAbpModule module)
{
(module as IOnApplicationInitialization)?.
OnApplicationInitialization(context);
}
}
public class OnApplicationShutdownModuleLifecycleContributor :
ModuleLifecycleContributorBase
{
public async override Task ShutdownAsync(
ApplicationShutdownContext context, IAbpModule module)
{
if (module is IOnApplicationShutdown onApplicationShutdown)
{
await onApplicationShutdown.OnApplicationShutdownAsync(context);
}
}
public override void Shutdown(
ApplicationShutdownContext context, IAbpModule module)
{
(module as IOnApplicationShutdown)?.OnApplicationShutdown(context);
}
}
public class OnPreApplicationInitializationModuleLifecycleContributor :
ModuleLifecycleContributorBase
{
public async override Task InitializeAsync(
ApplicationInitializationContext context, IAbpModule module)
{
if (module is IOnPreApplicationInitialization onPreApplicationInitialization)
{
await onPreApplicationInitialization.
OnPreApplicationInitializationAsync(context);
}
}
public override void Initialize(
ApplicationInitializationContext context, IAbpModule module)
{
(module as IOnPreApplicationInitialization)?.
OnPreApplicationInitialization(context);
}
}
public class OnPostApplicationInitializationModuleLifecycleContributor :
ModuleLifecycleContributorBase
{
public async override Task InitializeAsync(
ApplicationInitializationContext context, IAbpModule module)
{
if (module is IOnPostApplicationInitialization onPostApplicationInitialization)
{
await onPostApplicationInitialization.
OnPostApplicationInitializationAsync(context);
}
}
public override void Initialize(
ApplicationInitializationContext context, IAbpModule module)
{
(module as IOnPostApplicationInitialization)?.
OnPostApplicationInitialization(context);
}
}
IModuleLifecycleContributor -->ModuleLifecycleContributorBase-->以上四个类实现-->以上的实 现最终由 AbpModule 的 继承者的实现模块的生命周期还是依赖 AbpModule 实现类实现的生命周期方 法
IModuleManager
模块管理器 初始化模块及关闭模块,在这个过程中触发模块的生命周期,使用定义的四个生命周 期贡献器去实现模块的生命周期在 IModuleManager 里
public interface IModuleManager
{
Task InitializeModulesAsync([NotNull] ApplicationInitializationContext context);
void InitializeModules([NotNull] ApplicationInitializationContext context);
Task ShutdownModulesAsync([NotNull] ApplicationShutdownContext context);
void ShutdownModules([NotNull] ApplicationShutdownContext context);
}
public class ModuleManager : IModuleManager, ISingletonDependency
{
private readonly IModuleContainer _moduleContainer;
private readonly IEnumerable<IModuleLifecycleContributor> _lifecycleContributors;
private readonly ILogger<ModuleManager> _logger;
public ModuleManager(
//相关的所有模块
IModuleContainer moduleContainer,
ILogger<ModuleManager> logger,
//生命周期贡献器,定义的生命周期贡献器会加入 AbpModuleLifecycleOptions
//abp 要保证贡献器按照顺序加入,pre,on, post shout down 这样的顺序
IOptions<AbpModuleLifecycleOptions> options,
IServiceProvider serviceProvider)
{
_moduleContainer = moduleContainer;
_logger = logger;
//在 di 里找到所有的贡献器
_lifecycleContributors = options.Value
.Contributors
.Select(serviceProvider.GetRequiredService)
.Cast<IModuleLifecycleContributor>()
.ToArray();
}
public virtual async Task InitializeModulesAsync(
ApplicationInitializationContext context)
{
//按照 pre on post 的顺序执行模块的生命周期
foreach (var contributor in _lifecycleContributors)
{
//遍历所有的模块
foreach (var module in _moduleContainer.Modules)
{
try
{
await contributor.InitializeAsync(context, module.Instance);
}
catch (Exception ex)
{
throw new AbpInitializationException(
$"An error occurred during the initialize {contributor.GetType().
FullName} phase of the module {module.Type.AssemblyQualifiedName}:
{ex.Message}. See the inner exception for details.", ex);
}
}
}
_logger.LogInformation("Initialized all ABP modules.");
}
//同步版本
public void InitializeModules(ApplicationInitializationContext context)
{
foreach (var contributor in _lifecycleContributors)
{
foreach (var module in _moduleContainer.Modules)
{
try
{
contributor.Initialize(context, module.Instance);
}
catch (Exception ex)
{
throw new AbpInitializationException($"An error occurred during
the initialize {contributor.GetType().FullName} phase of the module
{module.Type.AssemblyQualifiedName}: {ex.Message}. See the inner
exception for details.", ex);
}
}
}
_logger.LogInformation("Initialized all ABP modules.");
}
//关闭
public virtual async Task ShutdownModulesAsync(ApplicationShutdownContext context)
{
var modules = _moduleContainer.Modules.Reverse().ToList();
foreach (var contributor in _lifecycleContributors)
{
foreach (var module in modules)
{
try
{
await contributor.ShutdownAsync(context, module.Instance);
}
catch (Exception ex)
{
throw new AbpShutdownException($"An error occurred during
the shutdown {contributor.GetType().FullName} phase of the
module {module.Type.AssemblyQualifiedName}: {ex.Message}.
See the inner exception for details.", ex);
}
}
}
}
public void ShutdownModules(ApplicationShutdownContext context)
{
var modules = _moduleContainer.Modules.Reverse().ToList();
foreach (var contributor in _lifecycleContributors)
{
foreach (var module in modules)
{
try
{
contributor.Shutdown(context, module.Instance);
}
catch (Exception ex)
{
throw new AbpShutdownException($"An error occurred
during the shutdown {contributor.GetType().FullName}
phase of the module {module.Type.AssemblyQualifiedName}:
{ex.Message}. See the inner exception for details.", ex);
}
}
}
}
}
IAbpApplication
所有的模块组合在一起就是 IAbpApplication, 此时模块自己的服务都组合进 IAbpApplication 里, 最后依赖在一起的所有的模块形成一个整体存在,服务配置及生命周期都在 AbpApplication 里完成
应用程序在加载完成所有相关的模块后具有的功能
public interface IAbpApplication :
IModuleContainer,
IApplicationInfoAccessor,
IDisposable
{
//启动模块
Type StartupModuleType { get; }
IServiceCollection Services { get; }
IServiceProvider ServiceProvider { get; }
//配置服务 模块的 pre post 配置服务都在这个方法里完成
Task ConfigureServicesAsync();
Task ShutdownAsync();
void Shutdown();
}
IConventionalRegistrar
约定注册 每个模块都有自己的约定注册
public interface IConventionalRegistrar
{
void AddAssembly(IServiceCollection services, Assembly assembly);
void AddTypes(IServiceCollection services, params Type[] types);
void AddType(IServiceCollection services, Type type);
}
public abstract class ConventionalRegistrarBase : IConventionalRegistrar
{
public virtual void AddAssembly(IServiceCollection services, Assembly assembly)
{
var types = AssemblyHelper
.GetAllTypes(assembly)
.Where(
type => type != null &&
type.IsClass &&
!type.IsAbstract &&
!type.IsGenericType
).ToArray();
AddTypes(services, types);
}
public virtual void AddTypes(IServiceCollection services, params Type[] types)
{
foreach (var type in types)
{
AddType(services, type);
}
}
//具体符合什么条件的可以被注入,留给抽象实现类
public abstract void AddType(IServiceCollection services, Type type);
}
public class DefaultConventionalRegistrar : ConventionalRegistrarBase{
//写约定注入的规则去注入,一种是实现接口,一种是用特性 Dependency
public override void AddType(IServiceCollection services, Type type)
{
if (IsConventionalRegistrationDisabled(type))
{
return;
}
// 获得 Dependency 特性,如果没有则返回 null。
var dependencyAttribute = GetDependencyAttributeOrNull(type);
// 优先使用 Dependency 特性所指定的生命周期,如果不存在则根据 type 实现的接口确定生命周期。
var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute);
if (lifeTime == null)
{
return;
}
// ExposeServicesAttribute 有选择方法
var exposedServiceTypes = GetExposedServiceTypes(type);
TriggerServiceExposing(services, type, exposedServiceTypes);
foreach (var exposedServiceType in exposedServiceTypes)
{
var serviceDescriptor = CreateServiceDescriptor(
type,
exposedServiceType,
exposedServiceTypes,
lifeTime.Value
);
if (dependencyAttribute?.ReplaceServices == true)
{
services.Replace(serviceDescriptor);
}
else if (dependencyAttribute?.TryRegister == true)
{
services.TryAdd(serviceDescriptor);
}
else
{
services.Add(serviceDescriptor);
}
}
}
}
AbpApplicationBase
抽象实现
public abstract class AbpApplicationBase : IAbpApplication{
public Type StartupModuleType { get; }
public IServiceProvider ServiceProvider { get; private set; } = default!;
public IServiceCollection Services { get; }
public IReadOnlyList<IAbpModuleDescriptor> Modules { get; }
public string? ApplicationName { get; }
public string InstanceId { get; } = Guid.NewGuid().ToString();
private bool _configuredServices;
//构造函数不能写异步方法,所以在构造函数里只做了同步模块服务注入
internal AbpApplicationBase(
Type startupModuleType,
IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction)
{
StartupModuleType = startupModuleType;
Services = services;
//这里增加一个对象存取器 是单例的, IServiceProvider 此时并没有被注入
//在抽象类的实现类里被注入,只是占个位置
services.TryAddObjectAccessor<IServiceProvider>();
//AbpApplication 的配置包括名字,读取配置文件的文件位置,环境变量
var options = new AbpApplicationCreationOptions(services);
//用户配置的选项
optionsAction?.Invoke(options);
//通过配置文件获取应用程序名,没有配置者通过程序集生成
ApplicationName = GetApplicationName(options);
//注入自己
services.AddSingleton<IAbpApplication>(this);
services.AddSingleton<IApplicationInfoAccessor>(this);
services.AddSingleton<IModuleContainer>(this);
//注入当前应用程序的环境变量名字
services.AddSingleton<IAbpHostEnvironment>(new AbpHostEnvironment()
{
EnvironmentName = options.Environment
});
/**
注入Application 需要的核心服务
配置选项
services.AddOptions();
日志
services.AddLogging();
本地化
services.AddLocalization();
*/
services.AddCoreServices();
/**
替换默认的配置用 applicationCreationOptions
if (!services.IsAdded<IConfiguration>())
{
services.ReplaceConfiguration(
ConfigurationHelper.BuildConfiguration(
applicationCreationOptions.Configuration
)
);
}
注入 abo 模块化需要的核心服务
ModuleLoader 加载 IAbpModuleDescriptor[],使用了拓扑排序算法解决模块相互依赖的问题
services.TryAddSingleton<IModuleLoader>(moduleLoader);
获取每个模块所在的程序集,内部是通过 ILazy 集合存放
services.TryAddSingleton<IAssemblyFinder>(assemblyFinder);
获取所有模块里的类型,内部是通过 ILazy 集合存放
services.TryAddSingleton<ITypeFinder>(typeFinder);
因为 IAbpApplication 接口所在的类 Volo.Abp.Core 本身,
并不是模块,这里的服务要单独注入一次
services.AddAssemblyOf<IAbpApplication>();
这个功能没有找到使用的目的
services.AddTransient(typeof(ISimpleStateCheckerManager<>),
typeof(SimpleStateCheckerManager<>));
给 AbpModuleLifecycleOptions(ITypeList<IModuleLifecycleContributor>
Contributors) 配置生命周期
生命周期最终的实现还是 IAbpModule 来实现
services.Configure<AbpModuleLifecycleOptions>(options =>
{
options.Contributors.Add<
OnPreApplicationInitializationModuleLifecycleContributor>();
options.Contributors.Add<
OnApplicationInitializationModuleLifecycleContributor>();
options.Contributors.Add<
OnPostApplicationInitializationModuleLifecycleContributor>();
options.Contributors.Add<
OnApplicationShutdownModuleLifecycleContributor>();
});
*/
services.AddCoreAbpServices(this, options);
//在上面注入一些基础的服务情况下,就可以加载模块了
//用 moduleLoader 加载模块描述集合
Modules = LoadModules(services, options);
if (!options.SkipConfigureServices)
{
ConfigureServices();
}
}
//实现接口,因为这个类 AbpApplicationBase 是new 出来的,这里没有注入
//IModuleManager,而是通过服务定位器的方法找到
public virtual async Task ShutdownAsync()
{
using (var scope = ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IModuleManager>()
.ShutdownModulesAsync(new ApplicationShutdownContext(scope.ServiceProvider));
}
}
//实现接口
public virtual void Shutdown()
{
using (var scope = ServiceProvider.CreateScope())
{
scope.ServiceProvider
.GetRequiredService<IModuleManager>()
.ShutdownModules(new ApplicationShutdownContext(scope.ServiceProvider));
}
}
protected virtual void SetServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
//给应用程序设置 IServiceProvider,之前在注入阶段只是注入了空的
//ObjectAccessor<IServiceProvider>,因为在应用程序 new 了之后,
//不能在给服务集合添加服务,故 使用 ObjectAccessor<IServiceProvider> 进行占位
ServiceProvider.GetRequiredService<ObjectAccessor<IServiceProvider>>().
Value = ServiceProvider;
}
//启动生命周期方法
protected virtual async Task InitializeModulesAsync()
{
using (var scope = ServiceProvider.CreateScope())
{
WriteInitLogs(scope.ServiceProvider);
await scope.ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModulesAsync(new ApplicationInitializationContext(
scope.ServiceProvider));
}
}
protected virtual void InitializeModules()
{
using (var scope = ServiceProvider.CreateScope())
{
WriteInitLogs(scope.ServiceProvider);
scope.ServiceProvider
.GetRequiredService<IModuleManager>()
.InitializeModules(new ApplicationInitializationContext(
scope.ServiceProvider));
}
}
//写初始化应用程序日志,对此次加载的所有模块进行初始日志记录
//todo 之后在写具体原理
protected virtual void WriteInitLogs(IServiceProvider serviceProvider)
{
var logger = serviceProvider.GetService<ILogger<AbpApplicationBase>>();
if (logger == null)
{
return;
}
var initLogger = serviceProvider.GetRequiredService<IInitLoggerFactory>().
Create<AbpApplicationBase>();
foreach (var entry in initLogger.Entries)
{
logger.Log(entry.LogLevel, entry.EventId, entry.State, entry.Exception,
entry.Formatter);
}
initLogger.Entries.Clear();
}
//配置服务异步
public virtual async Task ConfigureServicesAsync(){}
//装载模块描述符,主要使用的是拓扑算法
protected virtual IReadOnlyList<IAbpModuleDescriptor> LoadModules(
IServiceCollection services, AbpApplicationCreationOptions options)
{
return services
.GetSingletonInstance<IModuleLoader>()
.LoadModules(
services,
StartupModuleType,
options.PlugInSources
);
}
private static string? GetApplicationName(AbpApplicationCreationOptions options)
{
if (!string.IsNullOrWhiteSpace(options.ApplicationName))
{
return options.ApplicationName!;
}
var configuration = options.Services.GetConfigurationOrNull();
if (configuration != null)
{
var appNameConfig = configuration["ApplicationName"];
if (!string.IsNullOrWhiteSpace(appNameConfig))
{
return appNameConfig!;
}
}
var entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null)
{
return entryAssembly.GetName().Name;
}
return null;
}
private static void TryToSetEnvironment(IServiceCollection services)
{
var abpHostEnvironment = services.GetSingletonInstance<IAbpHostEnvironment>();
if (abpHostEnvironment.EnvironmentName.IsNullOrWhiteSpace())
{
abpHostEnvironment.EnvironmentName = Environments.Production;
}
}
}
ConfigureServices() 方法内部 AbpApplicationBase 提供了 ConfigureServices 同步方法
ConfigureServices
public virtual async Task ConfigureServicesAsync()
{
//在注入服务前,通过 _configuredServices 检查服务注入是否已经结束
CheckMultipleConfigureServices();
var context = new ServiceConfigurationContext(Services);
Services.AddSingleton(context);
//给注入的每个模块设置上下文
foreach (var module in Modules)
{
if (module.Instance is AbpModule abpModule)
{
abpModule.ServiceConfigurationContext = context;
}
}
//PreConfigureServices 先注入所有模块的 pre services
foreach (var module in Modules.Where(m => m.Instance is IPreConfigureServices))
{
try
{
await ((IPreConfigureServices)module.Instance).
PreConfigureServicesAsync(context);
}
catch (Exception ex)
{
throw new AbpInitializationException($"An error occurred during {
nameof(IPreConfigureServices.PreConfigureServicesAsync)} phase of the module
{module.Type.AssemblyQualifiedName}.
See the inner exception for details.", ex);
}
}
//
var assemblies = new HashSet<Assembly>();
//ConfigureServices
foreach (var module in Modules)
{
if (module.Instance is AbpModule abpModule)
{
//自动注入
if (!abpModule.SkipAutoServiceRegistration)
{
var assembly = module.Type.Assembly;
if (!assemblies.Contains(assembly))
{
//约定注入 通过程序集注入,每个模块的约定的服务
Services.AddAssembly(assembly);
assemblies.Add(assembly);
}
}
}
//正常的注入
try
{
await module.Instance.ConfigureServicesAsync(context);
}
catch (Exception ex)
{
throw new AbpInitializationException($"An error occurred during
{nameof(IAbpModule.ConfigureServicesAsync)} phase of the module
{module.Type.AssemblyQualifiedName}. See the inner exception for
details.", ex);
}
}
//PostConfigureServices 最后注入
foreach (var module in Modules.Where(m => m.Instance is IPostConfigureServices))
{
try
{
await ((IPostConfigureServices)module.Instance).
PostConfigureServicesAsync(context);
}
catch (Exception ex)
{
throw new AbpInitializationException($"An error occurred during
{nameof(IPostConfigureServices.PostConfigureServicesAsync)}
phase of the module {module.Type.AssemblyQualifiedName}.
See the inner exception for details.", ex);
}
}
//清除模块的上下文,保证之后模块不能在注入任何服务
foreach (var module in Modules)
{
if (module.Instance is AbpModule abpModule)
{
abpModule.ServiceConfigurationContext = null!;
}
}
// 做个标记,服务注入结束
_configuredServices = true;
//如果环境变更了的名字没有设置,给默认值
TryToSetEnvironment(Services);
}
AbpApplicationWithExternalServiceProvider
在 IAbpApplication 基础上增加初始化方法
public interface IAbpApplicationWithExternalServiceProvider : IAbpApplication
{
//外部提供 IServiceProvider
void SetServiceProvider([NotNull] IServiceProvider serviceProvider);
Task InitializeAsync([NotNull] IServiceProvider serviceProvider);
void Initialize([NotNull] IServiceProvider serviceProvider);
}
internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase,
IAbpApplicationWithExternalServiceProvider{
public AbpApplicationWithExternalServiceProvider(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction
) : base(
startupModuleType,
services,
optionsAction)
{
//注入自己
services.AddSingleton<IAbpApplicationWithExternalServiceProvider>(this);
}
//设置最为关键的 IServiceProvider
void IAbpApplicationWithExternalServiceProvider.SetServiceProvider(
[NotNull] IServiceProvider serviceProvider)
{
Check.NotNull(serviceProvider, nameof(serviceProvider));
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (ServiceProvider != null)
{
if (ServiceProvider != serviceProvider)
{
throw new AbpException("Service provider was already set
before to another service provider instance.");
}
return;
}
SetServiceProvider(serviceProvider);
}
//设置 serviceProvider 调用基类的初始化方法
public async Task InitializeAsync(IServiceProvider serviceProvider)
{
Check.NotNull(serviceProvider, nameof(serviceProvider));
SetServiceProvider(serviceProvider);
await InitializeModulesAsync();
}
public void Initialize([NotNull] IServiceProvider serviceProvider)
{
Check.NotNull(serviceProvider, nameof(serviceProvider));
SetServiceProvider(serviceProvider);
InitializeModules();
}
public override void Dispose()
{
base.Dispose();
if (ServiceProvider is IDisposable disposableServiceProvider)
{
disposableServiceProvider.Dispose();
}
}
}
AbpApplicationWithInternalServiceProvider
内部测试用
public interface IAbpApplicationWithInternalServiceProvider : IAbpApplication
{
//使用内部的 ServiceProvider
IServiceProvider CreateServiceProvider();
Task InitializeAsync();
void Initialize();
}
internal class AbpApplicationWithInternalServiceProvider : AbpApplicationBase,
IAbpApplicationWithInternalServiceProvider
{
public IServiceScope? ServiceScope { get; private set; }
public AbpApplicationWithInternalServiceProvider(
[NotNull] Type startupModuleType,
Action<AbpApplicationCreationOptions>? optionsAction
) : this(
startupModuleType,
new ServiceCollection(),
optionsAction)
{
}
private AbpApplicationWithInternalServiceProvider(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction
) : base(
startupModuleType,
services,
optionsAction)
{
Services.AddSingleton<IAbpApplicationWithInternalServiceProvider>(this);
}
public IServiceProvider CreateServiceProvider()
{
// ReSharper disable once
//ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (ServiceProvider != null)
{
return ServiceProvider;
}
ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope();
SetServiceProvider(ServiceScope.ServiceProvider);
return ServiceProvider!;
}
public async Task InitializeAsync()
{
CreateServiceProvider();
await InitializeModulesAsync();
}
public void Initialize()
{
CreateServiceProvider();
InitializeModules();
}
public override void Dispose()
{
base.Dispose();
ServiceScope?.Dispose();
}
}
AbpApplicationFactory
public static class AbpApplicationFactory
{
public async static Task<IAbpApplicationWithInternalServiceProvider>
CreateAsync<TStartupModule>(
Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule
{
var app = Create(typeof(TStartupModule), options =>
{
//已经配置过的服务,不在配置
options.SkipConfigureServices = true;
optionsAction?.Invoke(options);
});
//配置服务
await app.ConfigureServicesAsync();
return app;
}
public async static Task<IAbpApplicationWithInternalServiceProvider> CreateAsync(
[NotNull] Type startupModuleType,
Action<AbpApplicationCreationOptions>? optionsAction = null)
{
var app = new AbpApplicationWithInternalServiceProvider(startupModuleType,
options =>
{
options.SkipConfigureServices = true;
optionsAction?.Invoke(options);
});
await app.ConfigureServicesAsync();
return app;
}
//外部提供 DI ,生命周期跟随外部
public async static Task<IAbpApplicationWithExternalServiceProvider>
CreateAsync<TStartupModule>(
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule
{
var app = Create(typeof(TStartupModule), services, options =>
{
options.SkipConfigureServices = true;
optionsAction?.Invoke(options);
});
await app.ConfigureServicesAsync();
return app;
}
public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction = null)
{
var app = new AbpApplicationWithExternalServiceProvider(startupModuleType,
services, options =>
{
options.SkipConfigureServices = true;
optionsAction?.Invoke(options);
});
await app.ConfigureServicesAsync();
return app;
}
// 使用内部的 di 生命周期手动控制
public static IAbpApplicationWithInternalServiceProvider Create<TStartupModule>(
Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule
{
return Create(typeof(TStartupModule), optionsAction);
}
public static IAbpApplicationWithInternalServiceProvider Create(
[NotNull] Type startupModuleType,
Action<AbpApplicationCreationOptions>? optionsAction = null)
{
return new AbpApplicationWithInternalServiceProvider(startupModuleType,
optionsAction);
}
public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>(
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction = null)
where TStartupModule : IAbpModule
{
return Create(typeof(TStartupModule), services, optionsAction);
}
public static IAbpApplicationWithExternalServiceProvider Create(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? optionsAction = null)
{
return new AbpApplicationWithExternalServiceProvider(startupModuleType,
services, optionsAction);
}
}
IAbpApplicationWithExternalServiceProvider 和 asp.net core 结合
IHostedService 托管的服务
// host 的启动和停止的时候加载的方法,一些后台任务可以放在这里
// Kestrel web 服务器也是作为这种服务存在的,
public interface IHostedService
{
Task StartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
BackgroundService 长时间运行的托管服务
namespace Microsoft.Extensions.Hosting
{
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task? _executeTask;
private CancellationTokenSource? _stoppingCts;
public virtual Task? ExecuteTask => _executeTask;
/// <remarks>See <see href=
"https://docs.microsoft.com/dotnet/core/extensions/workers">Worker
Services in .NET</see> for implementation guidelines.</remarks>
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Create linked token to allow cancelling executing task from provided token
_stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(
cancellationToken);
// Store the task we're executing
_executeTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it,
this will bubble cancellation and failure to the caller
if (_executeTask.IsCompleted)
{
return _executeTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executeTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts!.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executeTask, Task.Delay(Timeout.Infinite,
cancellationToken)).ConfigureAwait(false);
}
}
public virtual void Dispose()
{
_stoppingCts?.Cancel();
}
}
}
IHost
// IHost 底层是 Host 实现类,不能被用户访问到的,是密封类
public interface IHost : IDisposable
{
IServiceProvider Services { get; }
// IHostedService 这里会启动 IHostedService 的实现类
Task StartAsync(CancellationToken cancellationToken = default);
//IHostedService 这里会停止 IHostedService 的实现类
Task StopAsync(CancellationToken cancellationToken = default);
}
// Host 底层要 IHostLifetime 去实现 ,启动的时候调用 IHostLifetime
//方法及做出通知 ApplicationLifetime
//同时调用受托管的服务 IEnumerable<IHostedService>
namespace Microsoft.Extensions.Hosting.Internal
{
internal sealed class Host : IHost, IDisposable, IAsyncDisposable
{
private readonly ILogger<Host> _logger;
private readonly IHostLifetime _hostLifetime;
private readonly ApplicationLifetime _applicationLifetime;
private readonly HostOptions _options;
private readonly IHostEnvironment _hostEnvironment;
private readonly PhysicalFileProvider _defaultProvider;
private IEnumerable<IHostedService> _hostedServices;
private volatile bool _stopCalled;
public Host(
IServiceProvider services,
IHostEnvironment hostEnvironment,
PhysicalFileProvider defaultProvider,
IHostApplicationLifetime applicationLifetime,
ILogger<Host> logger,
IHostLifetime hostLifetime,
IOptions<HostOptions> options)
{
ThrowHelper.ThrowIfNull((object) services, nameof (services));
ThrowHelper.ThrowIfNull((object) applicationLifetime, nameof (applicationLifetime));
ThrowHelper.ThrowIfNull((object) logger, nameof (logger));
ThrowHelper.ThrowIfNull((object) hostLifetime, nameof (hostLifetime));
this.Services = services;
this._applicationLifetime = applicationLifetime as ApplicationLifetime;
this._hostEnvironment = hostEnvironment;
this._defaultProvider = defaultProvider;
if (this._applicationLifetime == null)
throw new ArgumentException(SR.IHostApplicationLifetimeReplacementNotSupported,
nameof (applicationLifetime));
this._logger = logger;
this._hostLifetime = hostLifetime;
this._options = options?.Value ?? throw new ArgumentNullException(nameof (options));
}
public IServiceProvider Services { get; }
public async Task StartAsync(CancellationToken cancellationToken =
default (CancellationToken))
{
this._logger.Starting();
CancellationToken combinedCancellationToken;
using (CancellationTokenSource combinedCancellationTokenSource =
CancellationTokenSource.CreateLinkedTokenSource(cancellationToken,
this._applicationLifetime.ApplicationStopping))
{
combinedCancellationToken = combinedCancellationTokenSource.Token;
//_hostLifetime 启动
ConfiguredTaskAwaitable configuredTaskAwaitable =
this._hostLifetime.WaitForStartAsync(combinedCancellationToken).
ConfigureAwait(false);
await configuredTaskAwaitable;
combinedCancellationToken.ThrowIfCancellationRequested();
//启动托管服务
this._hostedServices =
this.Services.GetRequiredService<IEnumerable<IHostedService>>();
foreach (IHostedService hostedService in this._hostedServices)
{
configuredTaskAwaitable = hostedService.StartAsync(combinedCancellationToken).
ConfigureAwait(false);
await configuredTaskAwaitable;
if (hostedService is BackgroundService backgroundService)
this.TryExecuteBackgroundServiceAsync(backgroundService);
}
//外部通知启动
this._applicationLifetime.NotifyStarted();
this._logger.Started();
}
combinedCancellationToken = new CancellationToken();
}
private async Task TryExecuteBackgroundServiceAsync(
BackgroundService backgroundService)
{
Task backgroundTask = backgroundService.ExecuteTask;
if (backgroundTask == null)
{
backgroundTask = (Task) null;
}
else
{
try
{
await backgroundTask.ConfigureAwait(false);
backgroundTask = (Task) null;
}
catch (Exception ex)
{
if (this._stopCalled && backgroundTask.IsCanceled && ex
is OperationCanceledException)
{
backgroundTask = (Task) null;
}
else
{
this._logger.BackgroundServiceFaulted(ex);
if (this._options.BackgroundServiceExceptionBehavior !=
BackgroundServiceExceptionBehavior.StopHost)
{
backgroundTask = (Task) null;
}
else
{
this._logger.BackgroundServiceStoppingHost(ex);
//出现异常了要主动通知停止,调用方法
this._applicationLifetime.StopApplication();
backgroundTask = (Task) null;
}
}
}
}
}
public async Task StopAsync(CancellationToken cancellationToken =
default (CancellationToken))
{
this._stopCalled = true;
this._logger.Stopping();
using (CancellationTokenSource cts = new CancellationTokenSource(
this._options.ShutdownTimeout))
{
using (CancellationTokenSource linkedCts = CancellationTokenSource.
CreateLinkedTokenSource(cts.Token, cancellationToken))
{
CancellationToken token = linkedCts.Token;
//对外通知开始停止
this._applicationLifetime.StopApplication();
IList<Exception> exceptions = (IList<Exception>) new List<Exception>();
if (this._hostedServices != null)
{
//停止托管服务,先开的先停
foreach (IHostedService hostedService in this._hostedServices.
Reverse<IHostedService>())
{
try
{
await hostedService.StopAsync(token).ConfigureAwait(false);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
}
//对外通知停止
this._applicationLifetime.NotifyStopped();
try
{
//最后停止控制台
await this._hostLifetime.StopAsync(token).ConfigureAwait(false);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
if (exceptions.Count > 0)
{
AggregateException ex = new AggregateException(
"One or more hosted services failed to stop.",
(IEnumerable<Exception>) exceptions);
this._logger.StoppedWithException((Exception) ex);
throw ex;
}
token = new CancellationToken();
exceptions = (IList<Exception>) null;
}
}
this._logger.Stopped();
}
public void Dispose() => this.DisposeAsync().AsTask().GetAwaiter().GetResult();
public async ValueTask DisposeAsync()
{
ValueTask valueTask;
if (this._hostEnvironment.ContentRootFileProvider == this._defaultProvider)
{
valueTask = DisposeAsync((object) this._hostEnvironment.ContentRootFileProvider);
await valueTask.ConfigureAwait(false);
}
else
{
valueTask = DisposeAsync((object) this._hostEnvironment.ContentRootFileProvider);
await valueTask.ConfigureAwait(false);
valueTask = DisposeAsync((object) this._defaultProvider);
await valueTask.ConfigureAwait(false);
}
valueTask = DisposeAsync((object) this.Services);
await valueTask.ConfigureAwait(false);
static async ValueTask DisposeAsync(object o)
{
switch (o)
{
case IAsyncDisposable asyncDisposable:
await asyncDisposable.DisposeAsync().ConfigureAwait(false);
break;
case IDisposable disposable:
disposable.Dispose();
break;
}
}
}
}
}
IHostLifetime
//在 Host 对象的启动和停止方法里,调用的是 IHostLifetime 实现类 的方法 ,这个接口可以被控制台实现,
//作为一个 host 需要具备如下的生命周期
public interface IHostLifetime
{
Task WaitForStartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
// IHostLifetime 实现类在启动和停止的时候对外通知的一种机制,
//可以把通知的事情注册在 CancellationToken 上
public interface IHostApplicationLifetime
{
CancellationToken ApplicationStarted { get; }
CancellationToken ApplicationStopping { get; }
CancellationToken ApplicationStopped { get; }
//异常停止停止
void StopApplication();
}
public class ConsoleLifetime : IHostLifetime, IDisposable{
}
WebApplication
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
#nullable enable
namespace Microsoft.AspNetCore.Builder
public sealed class WebApplication :
IHost,
IDisposable,
IApplicationBuilder,
IEndpointRouteBuilder,
IAsyncDisposable
{
internal const string GlobalEndpointRouteBuilderKey = "__GlobalEndpointRouteBuilder";
#nullable disable
private readonly IHost _host;
private readonly List<EndpointDataSource> _dataSources = new List<EndpointDataSource>();
#nullable enable
internal WebApplication(IHost host)
{
this._host = host;
this.ApplicationBuilder = new ApplicationBuilder(host.Services,
(object) this.ServerFeatures);
this.Logger = host.Services.GetRequiredService<ILoggerFactory>()
.CreateLogger(this.Environment.ApplicationName ?? nameof (WebApplication));
this.Properties["__GlobalEndpointRouteBuilder"] = (object) this;
}
public IServiceProvider Services => this._host.Services;
public IConfiguration Configuration => this._host.Services.
GetRequiredService<IConfiguration>();
public IWebHostEnvironment Environment
{
get => this._host.Services.GetRequiredService<IWebHostEnvironment>();
}
public IHostApplicationLifetime Lifetime
{
get => this._host.Services.GetRequiredService<IHostApplicationLifetime>();
}
public ILogger Logger { get; }
public ICollection<string> Urls
{
get => this.ServerFeatures.GetRequiredFeature<IServerAddressesFeature>().Addresses;
}
IServiceProvider IApplicationBuilder.ApplicationServices
{
get => this.ApplicationBuilder.ApplicationServices;
set => this.ApplicationBuilder.ApplicationServices = value;
}
internal IFeatureCollection ServerFeatures
{
get => this._host.Services.GetRequiredService<IServer>().Features;
}
IFeatureCollection IApplicationBuilder.ServerFeatures => this.ServerFeatures;
internal IDictionary<string, object?> Properties => this.ApplicationBuilder.Properties;
IDictionary<string, object?> IApplicationBuilder.Properties => this.Properties;
internal ICollection<EndpointDataSource> DataSources
{
get => (ICollection<EndpointDataSource>) this._dataSources;
}
ICollection<EndpointDataSource> IEndpointRouteBuilder.DataSources => this.DataSources;
internal ApplicationBuilder ApplicationBuilder { get; }
IServiceProvider IEndpointRouteBuilder.ServiceProvider => this.Services;
public static WebApplication Create(string[]? args = null)
{
return new WebApplicationBuilder(new WebApplicationOptions()
{
Args = args
}).Build();
}
public static WebApplicationBuilder CreateBuilder()
{
return new WebApplicationBuilder(new WebApplicationOptions());
}
public static WebApplicationBuilder CreateBuilder(string[] args)
{
return new WebApplicationBuilder(new WebApplicationOptions()
{
Args = args
});
}
public static WebApplicationBuilder CreateBuilder(WebApplicationOptions options)
{
return new WebApplicationBuilder(options);
}
//启动
public Task StartAsync(CancellationToken cancellationToken =
default (CancellationToken))
{
//控制台启动及托管服务启动,及对外通知启动
return this._host.StartAsync(cancellationToken);
}
//停止
public Task StopAsync(CancellationToken cancellationToken =
default (CancellationToken))
{
//控制台停止及托管服务停止,及对外通知停止
return this._host.StopAsync(cancellationToken);
}
//
public Task RunAsync(string? url = null)
{
this.Listen(url);
return HostingAbstractionsHostExtensions.RunAsync(this);
}
public void Run(string? url = null)
{
this.Listen(url);
HostingAbstractionsHostExtensions.Run(this);
}
void IDisposable.Dispose() => this._host.Dispose();
public ValueTask DisposeAsync() => ((IAsyncDisposable) this._host).DisposeAsync();
internal RequestDelegate BuildRequestDelegate() => this.ApplicationBuilder.Build();
#nullable disable
RequestDelegate IApplicationBuilder.Build() => this.BuildRequestDelegate();
IApplicationBuilder IApplicationBuilder.New()
{
IApplicationBuilder applicationBuilder = this.ApplicationBuilder.New();
applicationBuilder.Properties.Remove("__GlobalEndpointRouteBuilder");
return applicationBuilder;
}
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
this.ApplicationBuilder.Use(middleware);
return (IApplicationBuilder) this;
}
#nullable disable
IApplicationBuilder IEndpointRouteBuilder.CreateApplicationBuilder()
{
return ((IApplicationBuilder) this).New();
}
private void Listen(string url)
{
if (url == null)
return;
ICollection<string> addresses = this.ServerFeatures.Get<IServerAddressesFeature>()
?.Addresses;
if (addresses == null)
throw new InvalidOperationException("Changing the URL is not supported because no
valid IServerAddressesFeature was found.");
if (addresses.IsReadOnly)
throw new InvalidOperationException("Changing the URL is not supported because
Addresses IsReadOnly.");
addresses.Clear();
addresses.Add(url);
}
}
}
namespace Microsoft.Extensions.Hosting
{
public static class HostingAbstractionsHostExtensions
{
public static void Start(this IHost host)
{
host.StartAsync().GetAwaiter().GetResult();
}
public static async Task StopAsync(this IHost host, TimeSpan timeout)
{
using CancellationTokenSource cts = new CancellationTokenSource(timeout);
await host.StopAsync(cts.Token).ConfigureAwait(false);
}
public static void WaitForShutdown(this IHost host)
{
host.WaitForShutdownAsync().GetAwaiter().GetResult();
}
public static void Run(this IHost host)
{
host.RunAsync().GetAwaiter().GetResult();
}
public static async Task RunAsync(this IHost host, CancellationToken token = default)
{
try
{
await host.StartAsync(token).ConfigureAwait(false);
await host.WaitForShutdownAsync(token).ConfigureAwait(false);
}
finally
{
if (host is IAsyncDisposable asyncDisposable)
{
await asyncDisposable.DisposeAsync().ConfigureAwait(false);
}
else
{
host.Dispose();
}
}
}
//启动及停止合并
public static async Task WaitForShutdownAsync(this IHost host,
CancellationToken token = default)
{
//外部通知
IHostApplicationLifetime applicationLifetime =
host.Services.GetRequiredService<IHostApplicationLifetime>();
//外部token 取消
token.Register(state =>
{
//触发 IHostApplicationLifetime 停止方法
((IHostApplicationLifetime)state!).StopApplication();
},
applicationLifetime);
var waitForStop = new TaskCompletionSource<object?>(
TaskCreationOptions.RunContinuationsAsynchronously);
applicationLifetime.ApplicationStopping.Register(obj =>
{
// waitForStop task 完成
var tcs = (TaskCompletionSource<object?>)obj!;
tcs.TrySetResult(null);
}, waitForStop);
//waitForStop 完成
await waitForStop.Task.ConfigureAwait(false);
//停止 host
await host.StopAsync(CancellationToken.None).ConfigureAwait(false);
}
}
}
abp 模块化 和 asp.net core 结合
var builder = WebApplication.CreateBuilder(args);
//此时 abp 使用 autofac 的 di 接管了 asp.net core 自带的服务 DI 进行服务解析
//但是此次服务还没有加入 autofac di
builder.Host.UseAutofac();
//把模块的注入的服务加入 asp.net core services collections
await builder.AddApplicationAsync<MyModule>();
生成 IAbpApplicationWithExternalServiceProvider AbpApplicationBase 的构造函数会把模块所 有的服务加入 asp.net core 的 services collections
public static class WebApplicationBuilderExtensions
{
//配置出一个 AbpApplicationWithExternalServiceProvider
public static async Task<IAbpApplicationWithExternalServiceProvider>
AddApplicationAsync<TStartupModule>(
[NotNull] this WebApplicationBuilder builder,
[CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
where TStartupModule : IAbpModule
{
/*
public async static Task<IAbpApplicationWithExternalServiceProvider>
AddApplicationAsync<TStartupModule>(
[NotNull] this IServiceCollection services,Action<AbpApplicationCreationOptions>?
optionsAction = null)
where TStartupModule : IAbpModule
{
return await AbpApplicationFactory.CreateAsync<TStartupModule>(services,
optionsAction);
}
*/
//对 Application 进行配置
return await builder.Services.AddApplicationAsync<TStartupModule>(
// AbpApplicationCreationOptions 配置选项
options =>
{
//原来的配置
options.Services.ReplaceConfiguration(builder.Configuration);
optionsAction?.Invoke(options);
if (options.Environment.IsNullOrWhiteSpace())
{
options.Environment = builder.Environment.EnvironmentName;
}
});
}
//。。。。。。。
}
AbpAutofacServiceProviderFactory
AbpAutofacServiceProviderFactory 提供给 asp.net core host 作为 依赖注入的 ServiceProviderFactory
public static class AbpAutofacHostBuilderExtensions
{
public static IHostBuilder UseAutofac(this IHostBuilder hostBuilder)
{
var containerBuilder = new ContainerBuilder();
return hostBuilder.ConfigureServices((_, services) =>
{
services.AddObjectAccessor(containerBuilder);
})
.UseServiceProviderFactory(new AbpAutofacServiceProviderFactory(
containerBuilder));
}
}
abp 提供的 AutofacServiceProviderFactory 工厂,autofac 也有类似的工厂
public class AbpAutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
{
private readonly ContainerBuilder _builder;
private IServiceCollection _services;
public AbpAutofacServiceProviderFactory(ContainerBuilder builder)
{
_builder = builder;
}
// WebApplicationBuilder Build 的时候会调用此方法
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
_services = services;
//把 asp.net core 注入的服务描述符,转换为 autofac 的组件描述符 注入 autofac 的容器
//这样才能通过 IServiceProvider 解析到服务
_builder.Populate(services);
return _builder;
}
//提供 ServiceProvider
public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
{
Check.NotNull(containerBuilder, nameof(containerBuilder));
//返回 autofac ServiceProvider
return new AutofacServiceProvider(containerBuilder.Build());
}
}
Populate 把 asp.net core 的 服务集合加入 autofac
abp 对 Autofac IoC container 扩展的方法,把 services collection 的服务描述符加入 di Autofac IoC container 本身有此方法,abp 进行了重构
public static class AutofacRegistration
{
//给 ContainerBuilder 添加 IServiceCollection
//Populate 英文单词居住于或增添数据的意思
public static void Populate(
this ContainerBuilder builder,
IServiceCollection services)
{
Populate(builder, services, null);
}
public static void Populate(
this ContainerBuilder builder,
IServiceCollection services,
object lifetimeScopeTagForSingletons)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
//
builder.RegisterType<AutofacServiceProvider>()
.As<IServiceProvider>()
//检查指定类型的服务是否可用
.As<IServiceProviderIsService>()
//生命周期由外部调用者控制
.ExternallyOwned();
var autofacServiceScopeFactory = typeof(AutofacServiceProvider).Assembly.
GetType("Autofac.Extensions.DependencyInjection.AutofacServiceScopeFactory");
if (autofacServiceScopeFactory == null)
{
throw new AbpException("Unable get type of Autofac.Extensions.
DependencyInjection.AutofacServiceScopeFactory!");
}
// autofacServiceScopeFactory 生成顶级作用域 root 的子作用域
builder
.RegisterType(autofacServiceScopeFactory)
.As<IServiceScopeFactory>()
.SingleInstance();
Register(builder, services, lifetimeScopeTagForSingletons);
}
// 把 asp.net core 的服务描述符注入 autofac 里
private static void Register(
ContainerBuilder builder,
IServiceCollection services,
object lifetimeScopeTagForSingletons)
{
//获取所有注入的 abp 模块
var moduleContainer = services.GetSingletonInstance<IModuleContainer>();
// 获取注册的行为
var registrationActionList = services.GetRegistrationActionList();
foreach (var descriptor in services)
{
if (descriptor.ImplementationType != null)
{
// Test if the an open generic type is being registered
var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo();
if (serviceTypeInfo.IsGenericTypeDefinition)
{
//泛型注入
builder
.RegisterGeneric(descriptor.ImplementationType)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime,
lifetimeScopeTagForSingletons)
//拦截器和属性注入
.ConfigureAbpConventions(moduleContainer,
registrationActionList);
}
else
{
builder
.RegisterType(descriptor.ImplementationType)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime,
lifetimeScopeTagForSingletons)
//拦截器和属性注入
.ConfigureAbpConventions(moduleContainer,
registrationActionList);
}
}
//工厂注入
else if (descriptor.ImplementationFactory != null)
{
var registration = RegistrationBuilder.ForDelegate(
descriptor.ServiceType, (context, parameters) =>
{
var serviceProvider = context.Resolve<IServiceProvider>();
// 调用描述符的工厂,内部会调用用户配置的委托方法
return descriptor.ImplementationFactory(serviceProvider);
})
.ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons)
.CreateRegistration();
// 注册组件
builder.RegisterComponent(registration);
}
//单例注入
else
{
builder
.RegisterInstance(descriptor.ImplementationInstance)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime, null);
}
}
}
//把 asp.net core 的生命周期转换为 autofac 的生命周期
private static IRegistrationBuilder<object, TActivatorData, TRegistrationStyle>
ConfigureLifecycle<TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<object, TActivatorData, TRegistrationStyle>
registrationBuilder,
ServiceLifetime lifecycleKind,
object lifetimeScopeTagForSingleton)
{
switch (lifecycleKind)
{
case ServiceLifetime.Singleton:
if (lifetimeScopeTagForSingleton == null)
{
registrationBuilder.SingleInstance();
}
else
{
//在匹配的生命周期里的单例
// using(var scope1 = container.BeginLifetimeScope("xxx"))
registrationBuilder.InstancePerMatchingLifetimeScope(
lifetimeScopeTagForSingleton);
}
break;
case ServiceLifetime.Scoped:
registrationBuilder.InstancePerLifetimeScope();
break;
case ServiceLifetime.Transient:
registrationBuilder.InstancePerDependency();
break;
}
return registrationBuilder;
}
}
WebApplicationBuilder Build
//生成 asp.net core 的 web application, web application 使用的是 autofac 的 DI,
//并最终把 asp.net core 的 服务加入 autofac di
var app = builder.Build();
// Build app 的第一件事情执行外部应用程序的生命周期方法,并执行外部应用程序的生命周期方法
// 外部应用程序的生命周期方法会依次执行模块的生命周期方法
await app.InitializeApplicationAsync();
在 build 后 di 注入服务的过程才结束,在 build 后不要在注入服务
public WebApplication Build()
{
this._hostApplicationBuilder.Services.Add(this._genericWebHostServiceDescriptor);
// 配置生成 ServiceProviderFactory 的委托
this.Host.ApplyServiceProviderFactory(this._hostApplicationBuilder);
// _hostApplicationBuilder.Build 调用生成 ServiceProviderFactory 的委托
//使用 _hostApplication 生成 WebApplication
this._builtApplication = new WebApplication(this._hostApplicationBuilder.Build());
return this._builtApplication;
}
public sealed class ConfigureHostBuilder : IHostBuilder, ISupportsConfigureWebHost{
internal void ApplyServiceProviderFactory(HostApplicationBuilder hostApplicationBuilder)
{
//没有外部工厂
if (_serviceProviderFactory is null)
{
// No custom factory. Avoid calling hostApplicationBuilder.ConfigureContainer()
which might override default validation options.
// If there were any callbacks supplied to ConfigureHostBuilder.
ConfigureContainer(), call those with the IServiceCollection.
foreach (var action in _configureContainerActions)
{
action(_context, _services);
}
return;
}
//使用外部工厂
void ConfigureContainerBuilderAdapter(object containerBuilder)
{
foreach (var action in _configureContainerActions)
{
action(_context, containerBuilder);
}
}
hostApplicationBuilder.ConfigureContainer(_serviceProviderFactory,
ConfigureContainerBuilderAdapter);
}
}
public sealed class HostApplicationBuilder{
public void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory
<TContainerBuilder> factory, Action<TContainerBuilder>?configure = null)
where TContainerBuilder : notnull
{
_createServiceProvider = () =>
{
//生成 autofac 的 containerBuilder, 把 asp.net core 的 服务加入
//autofac 的 di ,这里是比较重要的地方
TContainerBuilder containerBuilder = factory.CreateBuilder(Services);
//配置容器
_configureContainer(containerBuilder);
//使用 autofac 的 container 提供服务
return factory.CreateServiceProvider(containerBuilder);
};
// Store _configureContainer separately
//so it can replaced individually by the HostBuilderAdapter.
_configureContainer = containerBuilder =>
configure?.Invoke((TContainerBuilder)containerBuilder);
}
}
执行 abp 模块的生命周期
public static class AbpApplicationBuilderExtensions
{
private const string ExceptionHandlingMiddlewareMarker =
"_AbpExceptionHandlingMiddleware_Added";
public async static Task InitializeApplicationAsync(
[NotNull] this IApplicationBuilder app)
{
Check.NotNull(app, nameof(app));
app.ApplicationServices.GetRequiredService
<ObjectAccessor<IApplicationBuilder>>().Value = app;
//外部的 IAbpApplication
var application = app.ApplicationServices.GetRequiredService<
IAbpApplicationWithExternalServiceProvider>();
// asp.net core 应用程序生命周期钩子
var applicationLifetime = app.ApplicationServices.GetRequiredService<
IHostApplicationLifetime>();
//asp.net core 应用程序停止的时候,执行 外部的 IAbpApplication 的停止生命周期
applicationLifetime.ApplicationStopping.Register(() =>
{
AsyncHelper.RunSync(() => application.ShutdownAsync());
});
applicationLifetime.ApplicationStopped.Register(() =>
{
//销毁外部 IAbpApplication
application.Dispose();
});
//初始外部应用程序的初始化生命周期,
await application.InitializeAsync(app.ApplicationServices);
}
//同步版本
public static void InitializeApplication([NotNull] this IApplicationBuilder app)
{
Check.NotNull(app, nameof(app));
app.ApplicationServices.GetRequiredService<
ObjectAccessor<IApplicationBuilder>>().Value = app;
var application = app.ApplicationServices.GetRequiredService<
IAbpApplicationWithExternalServiceProvider>();
var applicationLifetime = app.ApplicationServices.GetRequiredService<
IHostApplicationLifetime>();
applicationLifetime.ApplicationStopping.Register(() =>
{
application.Shutdown();
});
applicationLifetime.ApplicationStopped.Register(() =>
{
application.Dispose();
});
application.Initialize(app.ApplicationServices);
}
}
abp 代理
Castle.DynamicProxy
Castle.DynamicProxy 是通过 Emit 反射动态生成代理类来实现的,代理可以进行组合形成拦截管道
- 类代理 只能代理虚方法,通过 additionalInterfacesToProxy 参数增加额外的接口
- CreateClassProxy,代理的目标是 Castle 生成
- CreateClassProxyWithTarget,代理的目标需要用户自己提供,需要用户 new 被代理的类
-
接口代理, 代理的目标对象都需要用户提供 任何公开的方法都能代理,通过
additionalInterfacesToProxy 参数增加额外的接口,同时代理多个接口,如下的俩个方法使用上没
有什么区别,CreateInterfaceProxyWithTargetInterface 在缓存方面更好
- CreateInterfaceProxyWithTarget
- CreateInterfaceProxyWithTargetInterface
- 只代理接口,没有实现类
- IProxyTargetAccessor 代理为转换为此接口可获取目标对象和拦截器
IInvocation 拦截的信息
public interface IInvocation
{
object[] Arguments { get; }
Type[] GenericArguments { get; }
object InvocationTarget { get; }
//代理对象的方法
MethodInfo Method { get; }
MethodInfo MethodInvocationTarget { get; }
object Proxy { get; }
object ReturnValue { get; set; }
Type TargetType { get; }
object GetArgumentValue(int index);
MethodInfo GetConcreteMethod();
MethodInfo GetConcreteMethodInvocationTarget();
//拦截器管线,调用下一个拦截器或最终的目标方法
void Proceed();
IInvocationProceedInfo CaptureProceedInfo();
void SetArgumentValue(int index, object value);
}
类代理 接口和对象同时代理
public interface ISpecificF {
public string Func();
}
public class SpecificF: ISpecificF {
public string Func() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
//如果是类代理,只有虚方法可以被代理
public virtual string Fun1() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
}
public class MyInterceptor:IInterceptor {
public void Intercept(IInvocation invocation) {
Console.WriteLine("开始 "+ invocation.TargetType?.Name+":"+ invocation.Method?.Name);
try {
invocation.Proceed();
}
catch (Exception e) {
Console.WriteLine("发生错误了 "+
invocation.TargetType?.Name+":"+ invocation.Method?.Name);
Console.WriteLine("结束 "+
invocation.TargetType?.Name+":"+ invocation.Method?.Name);
}
}
//类代理,同时通过 additionalInterfacesToProxy 参数指定额外增加的接口给代理的目标对象
var p= new ProxyGenerator();
var tmp= p.CreateClassProxy(typeof(SpecificF),
additionalInterfacesToProxy: new []{ typeof(ISpecificF) } ,
new MyInterceptor()) as ISpecificF;
//通过这种方式接口的方法也被代理了
var result= tmp?.Func();
//只能代理虚方法
var tmp= p.CreateClassProxy(typeof(SpecificF),
additionalInterfacesToProxy: new []{ typeof(ISpecificF) } ,
new MyInterceptor()) as SpecificF;
//和上面的写法一样
var tmp= p.CreateClassProxy(typeof(SpecificF), new MyInterceptor()) as SpecificF;
var result= tmp?.Func();
接口代理
public interface ISpecificF {
public string Func();
}
public interface ISpecificF1 {
public string Func1();
}
public class SpecificF: ISpecificF, ISpecificF1 {
public string Func() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
public string Func1() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
}
// 使用,只能转换为接口使用因为代理类是继承接口,并没有继承目标类
var p= new ProxyGenerator();
var tmp = p.CreateInterfaceProxyWithTargetInterface(
typeof(ISpecificF),
new Type[] {typeof(ISpecificF1) } ,
new SpecificF(),
new MyInterceptor()) as ISpecificF;
// 判断是接口代理
if (tmp.GetType().BaseType == typeof(SpecificF)) {
Console.WriteLine("类代理");
}
else {
Console.WriteLine("接口代理");
}
代理空接口,实现懒加载
public class MyInterceptor:IInterceptor {
private readonly Func<string> _func;
public MyInterceptor(Func<string> func) {
_func = func;
}
public void Intercept(IInvocation invocation) {
Console.WriteLine("开始 "+ invocation.TargetType?.Name+":"+ invocation.Method?.Name);
try {
//因为没有真正的实现不能 使用 invocation.Proceed();
//但是可以在 invocation 里获取参数
var result= _func.Invoke();
//空接口要返回值,需要用户自己返回
invocation.ReturnValue = "返回值";
}
catch (Exception e) {
Console.WriteLine("发生错误了 "+ invocation.TargetType?.Name+":"+
invocation.Method?.Name);
}
Console.WriteLine("结束 "+ invocation.TargetType?.Name+":"+ invocation.Method?.Name);
}
}
// 这种类型的拦截器,像是变戏法一样,生成一个继承接口的代理类,ISpecificF
// 接口的方法执行的时候都会执行代理类
var p= new ProxyGenerator();
var tmp = p.CreateInterfaceProxyWithoutTarget<ISpecificF>(new MyInterceptor(()=>"执行委托"));
//接口的方法有代理类实现
var i= tmp.Func();
Console.WriteLine(i);
懒加载示例
//定义拦截器
public class LazyLoadInterceptor : IInterceptor
{
private readonly Func<object> _loader;
//缓存的对象
private object _value;
public LazyLoadInterceptor(Func<object> loader)
{
_loader = loader;
}
public void Intercept(IInvocation invocation)
{
if (_value == null)
{
//对象真正的加载,通过这种方式达到延迟加载的目的,
//因为创造这个对象成本很高,只有调用对象的一些方法或属性的时候才加载
_value = _loader.Invoke();
}
//拦截器执行方法的最后调用
invocation.ReturnValue = invocation.Method.Invoke(_value, invocation.Arguments);
}
}
//懒加载的对象
public class MyLazyObject
{
private readonly LazyLoadInterceptor _interceptor;
public MyLazyObject(Func<object> loader)
{
_interceptor = new LazyLoadInterceptor(loader);
}
public T CreateProxy<T>() where T : class
{
var generator = new ProxyGenerator();
return generator.CreateInterfaceProxyWithoutTarget<T>(_interceptor);
}
}
//
var myLazyObject = new MyLazyObject(() => new ExpensiveObject());
var proxy = myLazyObject.CreateProxy<IExpensiveObject>();
// 在这里访问IExpensiveObject的属性或方法的时候才会去构造 ExpensiveObject
proxy.DoSomething();
拦截器选项 对代理的过程进行干预
ProxyGenerationOptions 类提供的属性进行自定义拦截的选项,过于随意地使用代理生成钩子和拦截器 选择器可能会大大降低代理类型缓存的效率,这可能会损害您的性能有趣的是你可以在返回的拦截器里 直接 new 新的拦截器
有如下的属性
public interface IInterceptorSelector
{
// 在方法拦截前进行过滤的,参数 type 拦截的 target 类型,method 拦截的方法,所有可以使用的拦截器
// 返回所有可以使用的拦截器
IInterceptor[] SelectInterceptors(Type type, MethodInfo method,
IInterceptor[] interceptors);
}
public interface IProxyGenerationHook{
//在生成代理时,这个方法会在检查每个方法之后被调用
void MethodsInspected();
//当无法代理某个成员时(例如私有成员),这个方法会被调用
void NonProxyableMemberNotification(Type type, MemberInfo memberInfo);
//决定是否要拦截特定方法的调用,可以在这里决定某个方法是否被拦截
bool ShouldInterceptMethod(Type type, MethodInfo methodInfo);
}
IInterceptorSelector
public interface ISpecificF {
//自动属性
public string Name { get; set; }
public string Func();
}
public class SpecificF: ISpecificF {
public string Name { get; set; }
public string Func() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
}
public class MyInterceptor:IInterceptor {
public void Intercept(IInvocation invocation) {
Console.WriteLine("开始 "+ invocation.TargetType?.Name+":"+ invocation.Method?.Name);
try {
invocation.Proceed();
}
catch (Exception e) {
Console.WriteLine("发生错误了 "+ invocation.TargetType?.Name+":"+
invocation.Method?.Name);
}
Console.WriteLine("结束 "+ invocation.TargetType?.Name+":"+ invocation.Method?.Name);
}
}
//拦截选择器
public class FreezableInterceptorSelector : IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method,
IInterceptor[] interceptors) {
//不拦截 set get 方法
return IsSetter(method)|| IsGetter(method) ? Array.Empty<IInterceptor>() :
interceptors;
}
//默认 set 方法也会拦截
private static bool IsSetter( MethodInfo method ) =>
method.IsSpecialName && method.Name.StartsWith( "set_", StringComparison.Ordinal );
//默认 get 方法 也会拦截
private static bool IsGetter( MethodInfo method ) =>
method.IsSpecialName && method.Name.StartsWith( "get_", StringComparison.Ordinal );
}
var p= new ProxyGenerator();
var tmp = p.CreateInterfaceProxyWithTargetInterface(
typeof(ISpecificF),
new SpecificF(),
new ProxyGenerationOptions() {
//拦截选择器
Selector = new FreezableInterceptorSelector()
},
new MyInterceptor()) as ISpecificF;
//被拦截
tmp.Func();
//没有拦截
tmp.Name = "jim";
var foo = tmp.Name;
Mixin
public interface ISpecificF {
public string Func();
}
public interface ISpecificF1 {
public string Func();
}
public class SpecificF: ISpecificF {
public string Func() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
}
public class SpecificF1: ISpecificF1 {
public string Func() {
return DateTime.Now.ToString(CultureInfo.InvariantCulture)+"----->";
}
}
public class MyInterceptor:IInterceptor {
public void Intercept(IInvocation invocation) {
Console.WriteLine("开始 "+ invocation.TargetType.Name+":"+ invocation.Method.Name);
try {
invocation.Proceed();
}
catch (Exception e) {
Console.WriteLine("发生错误了 "+ invocation.TargetType.Name+":"+
invocation.Method.Name);
}
Console.WriteLine("结束 "+ invocation.TargetType.Name+":"+ invocation.Method.Name);
}
}
var opt = new ProxyGenerationOptions() {
};
//混入的对象 SpecificF1
opt.AddMixinInstance(new SpecificF1());
var p= new ProxyGenerator();
var tmp = p.CreateInterfaceProxyWithTargetInterface(
typeof(ISpecificF),
//混入对象 暴露的接口 ISpecificF1
additionalInterfacesToProxy:new Type[]{ typeof(ISpecificF1)},
new SpecificF(),
opt,
// 转换为混入接口
new MyInterceptor()) as ISpecificF1;
tmp.Func();
IProxyGenerationHook 对方法是否被代理进行更细粒度的控制
public class FreezableProxyGenerationHook:IProxyGenerationHook
{
public void MethodsInspected() {
}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) {
Console.WriteLine(memberInfo.Name +"方法没有被代理");
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo) {
return methodInfo.Name.StartsWith("Func1", StringComparison.Ordinal);
}
}
var p= new ProxyGenerator();
var tmp = p.CreateInterfaceProxyWithTargetInterface(
typeof(ISpecificF),
new Type[] {typeof(ISpecificF1) } ,
new SpecificF(),
new ProxyGenerationOptions() {
//是在 hook
Hook = new FreezableProxyGenerationHook()
},
new MyInterceptor()) as ISpecificF1;
tmp.Func1();
代理异步方法
Castle.Core.AsyncInterceptor,AsyncInterceptor 是 Castle DynamicProxy 的扩展 简化异步方法 拦截器的开发,代理异步方法只要实现 IAsyncInterceptor 接口就可以在内部是通过 把 IAsyncInterceptor 拦截器转换为 AsyncDeterminationInterceptor 实现的 AsyncDeterminationInterceptor 继承自 IInterceptor
//异步的拦截器里,同时需要处理同步的方法,因为被代理类里有可能同时存在异步和同步方法
public class MyInterceptor:IAsyncInterceptor {
public void InterceptSynchronous(IInvocation invocation) {
Console.WriteLine("同步开始");
invocation.Proceed();
Console.WriteLine("同步结束");
}
public void InterceptAsynchronous(IInvocation invocation) {
Console.WriteLine("异步开始");
invocation.Proceed();
Console.WriteLine("异步不带返回值" + invocation.ReturnValue);
Console.WriteLine("异步结束");
}
public void InterceptAsynchronous<TResult>(IInvocation invocation) {
Console.WriteLine("异步带返回值开始");
invocation.Proceed();
// 获取返回值
var task= invocation.ReturnValue as Task<TResult>;
task?.ContinueWith(p => {
if (p.Status == TaskStatus.RanToCompletion) {
Console.WriteLine("异步带返回值"+p.Result);
}
});
Console.WriteLine("异步带返回值结束");
}
}
简化的 异步方法 AsyncInterceptorBase
AsyncInterceptorBase 继承自 IAsyncInterceptor
public class MyAsyncInterceptor : AsyncInterceptorBase
{
protected override async Task InterceptAsync(
IInvocation invocation,
IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task> proceed)
{
await proceed(invocation, proceedInfo).ConfigureAwait(false);
}
protected override async Task<TResult> InterceptAsync<TResult>(
IInvocation invocation,
IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
{
TResult result = await proceed(invocation, proceedInfo).ConfigureAwait(false);
return result;
}
}
泛型的代理
类似这种非常通用的拦截是不支持的
var tmp = p.CreateClassProxy(
typeof(SpecificF<>),
additionalInterfacesToProxy: new Type[] { typeof(ISpecificF<>) } ,
new MyInterceptor()
);
只能通过工厂模式稍微简化下工作量了
public ISpecificF<T>? GetProxyFactory<T>(Type classToProxy,
Type[] additionalInterfacesToProxy, params IAsyncInterceptor[] myInterceptor) {
var p = new ProxyGenerator();
return p.CreateClassProxy(
classToProxy,
additionalInterfacesToProxy: additionalInterfacesToProxy,
myInterceptor
) as ISpecificF<T>;
}
autofac 添加拦截器
Autofac.Extras.DynamicProxy 提供拦截器
类拦截
public interface ISpecificF {
public string Func();
}
public interface IFoo {
}
public class SpecificF: ISpecificF,IFoo {
//类拦截虚方法
public virtual string Func() {
return DateTime.Now.ToString();
}
}
var containerBuilder= context.Services.GetContainerBuilder();
containerBuilder.RegisterType<MyInterceptor>();
containerBuilder.RegisterType<SpecificF>().EnableClassInterceptors()
.InterceptedBy(typeof(MyInterceptor));
[HttpGet()]
public async Task<ActionResult> Get() {
var _specificF= _serviceProvider.GetService<SpecificF>();
_specificF.Func();
//类拦截会继承所有的接口
var interfaces= _specificF.GetType().GetInterfaces();
//类拦截是继承自目标类,这里的 baseType 是 SpecificF
var baseType= _specificF.GetType().BaseType;
//构造器传入参数是拦截器数组
var con = _specificF.GetType().GetConstructors().FirstOrDefault();
return Ok();
}
接口拦截
var containerBuilder= context.Services.GetContainerBuilder();
containerBuilder.RegisterType<MyInterceptor>();
//接口拦截
containerBuilder.RegisterType<SpecificF>().As<ISpecificF>().EnableInterfaceInterceptors()
.InterceptedBy(typeof(MyInterceptor));
[HttpGet()]
public async Task<ActionResult> Get() {
var _specificF= _serviceProvider.GetService<ISpecificF>();
_specificF.Func();
//接口拦截会继承所有的接口
var interfaces= _specificF.GetType().GetInterfaces();
//接口拦截不会继承目标类型,这里的 baseType 是 Object
var baseType= _specificF.GetType().BaseType;
//构造器传入参数是拦截器数组及目标对象
var con = _specificF.GetType().GetConstructors().FirstOrDefault();
return Ok();
}
IAbpInterceptor ABP 拦截器
在 abp core 里定义了基本的拦截器接口,ABP 定义了自己的拦截器接口及拦截信息
public interface IAbpInterceptor
{
// abp 合并同步和异步方法的拦截
Task InterceptAsync(IAbpMethodInvocation invocation);
}
// 通过这个参数概括了拦截到的信息
public interface IAbpMethodInvocation
{
object[] Arguments { get; }
IReadOnlyDictionary<string, object> ArgumentsDictionary { get; }
Type[] GenericArguments { get; }
object TargetObject { get; }
MethodInfo Method { get; }
object ReturnValue { get; set; }
Task ProceedAsync();
}
// abp 定义抽象的异步拦截器,,异步的返回值也可以在 IAbpMethodInvocation 里进行获取
public abstract class AbpInterceptor : IAbpInterceptor
{
public abstract Task InterceptAsync(IAbpMethodInvocation invocation);
}
//为了避免性能损失,Abp框架可以为某些组件(UOW、审计、授权等)启用拦截器,这需要动态代理类,
//但会导致应用程序性能下降。
// 可以使用控制器的其他方法来实现拦截,例如中间件或 MVC / Page过滤器。就可以避免这部分损失,
//abp 默认对 controller , view page 不使用拦截器
public static class DynamicProxyIgnoreTypes
{
private static HashSet<Type> IgnoredTypes { get; } = new HashSet<Type>();
public static void Add<T>()
{
lock (IgnoredTypes)
{
IgnoredTypes.AddIfNotContains(typeof(T));
}
}
public static bool Contains(Type type, bool includeDerivedTypes = true)
{
lock (IgnoredTypes)
{
return includeDerivedTypes
? IgnoredTypes.Any(t => t.IsAssignableFrom(type))
: IgnoredTypes.Contains(type);
}
}
}
// abp 提供的获取代理对象目标对象的方法, castle 也有类似的方法
public static class ProxyHelper
{
private const string ProxyNamespace = "Castle.Proxies";
public static object UnProxy(object obj)
{
if (obj.GetType().Namespace != ProxyNamespace)
{
return obj;
}
var targetField = obj.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.FirstOrDefault(f => f.Name == "__target");
if (targetField == null)
{
return obj;
}
return targetField.GetValue(obj)!;
}
public static Type GetUnProxiedType(object obj)
{
if (obj.GetType().Namespace == ProxyNamespace)
{
var target = UnProxy(obj);
if (target == obj)
{
return obj.GetType().GetTypeInfo().BaseType!;
}
return target.GetType();
}
return obj.GetType();
}
}
CastleAbpMethodInvocationAdapter
转换 Castle 的 IInvocation 为 abp 的 IAbpMethodInvocation
Volo.Abp.Castle.Core
CastleAbpMethodInvocationAdapterBase 相比 Castle 的 IInvocation 就是合并了一些属性
public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocation
{
public object[] Arguments => Invocation.Arguments;
public IReadOnlyDictionary<string, object> ArgumentsDictionary =>
_lazyArgumentsDictionary.Value;
private readonly Lazy<IReadOnlyDictionary<string, object>>
_lazyArgumentsDictionary;
public Type[] GenericArguments => Invocation.GenericArguments;
public object TargetObject => Invocation.InvocationTarget ??
Invocation.MethodInvocationTarget;
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method;
public object ReturnValue { get; set; }
protected IInvocation Invocation { get; }
// Castle.DynamicProxy --> IInvocation 通过 invocation 实现 IAbpMethodInvocation
protected CastleAbpMethodInvocationAdapterBase(IInvocation invocation)
{
Invocation = invocation;
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>
(GetArgumentsDictionary);
}
public abstract Task ProceedAsync();
private IReadOnlyDictionary<string, object> GetArgumentsDictionary()
{
var dict = new Dictionary<string, object>();
var methodParameters = Method.GetParameters();
for (int i = 0; i < methodParameters.Length; i++)
{
dict[methodParameters[i].Name] = Invocation.Arguments[i];
}
return dict;
}
}
CastleAbpMethodInvocationAdapter 拦截信息适配器
无返回值的 CastleAbpMethodInvocationAdapter
public class CastleAbpMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase,
IAbpMethodInvocation
{
protected IInvocationProceedInfo ProceedInfo { get; }
protected Func<IInvocation, IInvocationProceedInfo, Task> Proceed { get; }
// 传入 Castle 的 IInvocation invocation, IInvocationProceedInfo proceedInfo
public CastleAbpMethodInvocationAdapter(IInvocation invocation,
IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task> proceed)
: base(invocation)
{
ProceedInfo = proceedInfo;
Proceed = proceed;
}
//调用下一个拦截器或目标方法
public override async Task ProceedAsync()
{
//拿到的 Invocation 拦截信息 及最终的 处理的 ProceedInfo
await Proceed(Invocation, ProceedInfo);
}
}
有返回值的异步 CastleAbpMethodInvocationAdapterWithReturnValue
public class CastleAbpMethodInvocationAdapterWithReturnValue<TResult>
: CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation
{
protected IInvocationProceedInfo ProceedInfo { get; }
protected Func<IInvocation, IInvocationProceedInfo, Task<TResult>> Proceed { get; }
public CastleAbpMethodInvocationAdapterWithReturnValue(IInvocation invocation,
IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
: base(invocation)
{
ProceedInfo = proceedInfo;
Proceed = proceed;
}
public override async Task ProceedAsync()
{
ReturnValue = await Proceed(Invocation, ProceedInfo);
}
}
CastleAsyncAbpInterceptorAdapter
异步拦截器 AsyncInterceptorBase 是 Castle.DynamicProxy 封装的异步拦截器,abp 基于它进行的 适配 CastleAsyncAbpInterceptorAdapter,此适配器的目的把 AsyncInterceptorBase 方法的参数 适 配到 IAbpInterceptor 接口方法上去
因为 IAbpInterceptor 是 abp 自己定义的异步拦截器,abp 对方法需要的参数进行了整合 IInvocation -->IAbpMethodInvocation --> CastleAbpMethodInvocationAdapter 需要 CastleAbpMethodInvocationAdapter 把 IInvocation 整合到 IAbpMethodInvocation 上 ,IAbpMethodInvocation 是 abp 自己定义的,归根结底 abp 异步靠的是 Castle.DynamicProxy 的 AsyncInterceptorBase 实现的
AsyncInterceptorBase 实现的是 IAsyncInterceptor 接口,AsyncDeterminationInterceptor 实现的 是 IInterceptor 接口,但是在构造函数里传入 IAsyncInterceptor ,在同步方法里也实现了异步拦 截。接口,AsyncDeterminationInterceptor 实现了异步拦截器转换为同步拦截器,去适配 castle 的 拦截器
public class CastleAsyncAbpInterceptorAdapter<TInterceptor> : AsyncInterceptorBase
where TInterceptor : IAbpInterceptor
{
private readonly TInterceptor _abpInterceptor;
public CastleAsyncAbpInterceptorAdapter(TInterceptor abpInterceptor)
{
_abpInterceptor = abpInterceptor;
}
protected override async Task InterceptAsync(IInvocation invocation,
IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo,
Task> proceed)
{
await _abpInterceptor.InterceptAsync(
//转换 abp 的 Invocation 为 castle 的 Invocation
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed)
);
}
protected override async Task<TResult> InterceptAsync<TResult>(
IInvocation invocation, IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
{
//转换 abp 的 Invocation 为 castle 的 Invocation
var adapter = new CastleAbpMethodInvocationAdapterWithReturnValue
<TResult>(invocation, proceedInfo, proceed);
await _abpInterceptor.InterceptAsync(
adapter
);
return (TResult)adapter.ReturnValue;
}
}
AbpAsyncDeterminationInterceptor
AbpAsyncDeterminationInterceptor 不同于 AsyncInterceptorBase 的是这个拦截器自动识别被拦截 方法是否是异步方法,并在适当的时候进行处理,也是基于 Castle.DynamicProxy 的 AsyncDeterminationInterceptor 实现的
AsyncInterceptorBase 实现的是 IAsyncInterceptor 接口,AsyncDeterminationInterceptor 实现的 是 IInterceptor 接口,但是在构造函数里传入 IAsyncInterceptor ,在同步方法里也实现了异步拦 截
// AsyncDeterminationInterceptor 实现的是 同步接口 IInterceptor
public class AbpAsyncDeterminationInterceptor<TInterceptor> : AsyncDeterminationInterceptor
where TInterceptor : IAbpInterceptor
{
public AbpAsyncDeterminationInterceptor(TInterceptor abpInterceptor)
// AsyncDeterminationInterceptor 构造函数需要传入 IAsyncInterceptor 接口
// CastleAsyncAbpInterceptorAdapter 依赖 AsyncInterceptorBase 实现,
//IAsyncInterceptor 接口AsyncInterceptorBase 里实现的是
//使用适配器转换为把 abp 的拦截器转换为 castle 的拦截器
: base(new CastleAsyncAbpInterceptorAdapter<TInterceptor>(abpInterceptor))
{
}
}
//模块 AbpCastleCoreModule 最后导出的是 AbpAsyncDeterminationInterceptor,
//通过它定义的拦截器 会实现同步的,异步的方法拦截,它是最后的出口
public class AbpCastleCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient(typeof(AbpAsyncDeterminationInterceptor<>));
}
}
AsyncDeterminationInterceptor
Castle.DynamicProxy 内部的 AsyncDeterminationInterceptor 类
//在同步的连接器里同时处理异步的方法,此类要求传递 IAsyncInterceptor 作为参数
//在接口 IInterceptor 的方法里同时处理异步和同步方法
public class AsyncDeterminationInterceptor : IInterceptor{
//处理异步带返回值
private static void HandleAsyncWithResult<TResult>(IInvocation invocation,
IAsyncInterceptor asyncInterceptor)
{
asyncInterceptor.InterceptAsynchronous<TResult>(invocation);
}
//获取处理异步带返回值函数
private static readonly MethodInfo HandleAsyncMethodInfo =
typeof(AsyncDeterminationInterceptor)
.GetMethod(nameof(HandleAsyncWithResult), BindingFlags.Static |
BindingFlags.NonPublic)!;
// 带返回值的异步
private delegate void GenericAsyncHandler(IInvocation invocation,
IAsyncInterceptor asyncInterceptor);
// 返回值类型和拦截器字典,注意此处是静态属性,会把 多个
//AsyncDeterminationInterceptor 实例的拦截器和返回值进行绑定到字典
// 因为 AsyncDeterminationInterceptor 它实现的是 IInterceptor
//同步接口,没有办法正 AsyncDeterminationInterceptor 上体现异步泛型参数
private static readonly ConcurrentDictionary<Type, GenericAsyncHandler>
GenericAsyncHandlers =
new ConcurrentDictionary<Type, GenericAsyncHandler>();
//传入异步拦截器
public AsyncDeterminationInterceptor(IAsyncInterceptor asyncInterceptor)
{
AsyncInterceptor = asyncInterceptor;
}
public IAsyncInterceptor AsyncInterceptor { get; }
// 实现接口
public virtual void Intercept(IInvocation invocation)
{
MethodType methodType = GetMethodType(invocation.Method.ReturnType);
switch (methodType)
{
case MethodType.AsyncAction:
AsyncInterceptor.InterceptAsynchronous(invocation);
return;
case MethodType.AsyncFunction:
//有返回值异步
//这里之所以写的如此复杂,是为了把异步的带返回值的包装成一个委托传递给
// AsyncInterceptor 去处理
//这种写法为了把返回类型 和处理方法保存到字典里去,普通的方法没办法直接保存到字典里
GetHandler(invocation.Method.ReturnType).Invoke(invocation, AsyncInterceptor);
return;
default:
//同步方法
AsyncInterceptor.InterceptSynchronous(invocation);
return;
}
}
//
private enum MethodType
{
//同步方法
Synchronous,
//异步没返回值
AsyncAction,
//异步有返回值
AsyncFunction,
}
//获取返回类型,据此判断是同步还是异步
private static MethodType GetMethodType(Type returnType)
{
// If there's no return type, or it's not a task,
// then assume it's a synchronous method.
if (returnType == typeof(void) ||
!typeof(Task).IsAssignableFrom(returnType))
return MethodType.Synchronous;
// The return type is a task of some sort, so assume it's asynchronous
return returnType.GetTypeInfo().IsGenericType ?
MethodType.AsyncFunction : MethodType.AsyncAction;
}
//返回类型对应的拦截器
private static GenericAsyncHandler GetHandler(Type returnType)
{
GenericAsyncHandler handler = GenericAsyncHandlers.GetOrAdd(returnType, CreateHandler);
return handler;
}
}
//用返回类型转换为一个委托,用来传递给处理异步的带返回值的拦截器
private static GenericAsyncHandler CreateHandler(Type returnType)
{
Type taskReturnType = returnType.GetGenericArguments()[0];
MethodInfo method = HandleAsyncMethodInfo.MakeGenericMethod(taskReturnType);
//方法转成委托
return (GenericAsyncHandler)method.CreateDelegate(typeof(GenericAsyncHandler));
}
abp 对 Castle.DynamicProxy 封装 和 autofac 结合
abp 里可以手动注入拦截器
public override void ConfigureServices(ServiceConfigurationContext context) {
//拦截器注册
var serviceProvider = context.Services.BuildServiceProvider();
var containerBuilder= serviceProvider.
GetRequiredService<IObjectAccessor<ContainerBuilder>>()?.Value;
//代理参数
var opt=ProxyGenerationOptions.Default;
//绑定注入的服务和拦截器,接口拦截
containerBuilder?.RegisterType<SpecificF>().As<ISpecificF>().
EnableInterfaceInterceptors(opt)
.InterceptedBy(typeof(MyInterceptor));
//拦截器本身也要注入
containerBuilder?.RegisterType<MyInterceptor>();
}
IOnServiceRegistredContext
abp 拦截器上下文
public interface IOnServiceRegistredContext
{
//实现类绑定的所有拦截器
ITypeList<IAbpInterceptor> Interceptors { get; }
//实现类
Type ImplementationType { get; }
}
// 注册的接口及类型及拦截器集合,在注册服务的过程中,可以给集合添加 Interceptors 拦截器
public class OnServiceRegistredContext : IOnServiceRegistredContext
{
public virtual ITypeList<IAbpInterceptor> Interceptors { get; }
//导出的了类型
public virtual Type ServiceType { get; }
public virtual Type ImplementationType { get; }
public OnServiceRegistredContext(Type serviceType, [NotNull] Type implementationType)
{
ServiceType = Check.NotNull(serviceType, nameof(serviceType));
ImplementationType = Check.NotNull(implementationType, nameof(implementationType));
Interceptors = new TypeList<IAbpInterceptor>();
}
}
AbpRegistrationBuilderExtensions
//通过委托集合进行拦截器的添加,方便最后统一添加拦截器给注入的服务
public class ServiceRegistrationActionList : List<Action<IOnServiceRegistredContext>>
{
public bool IsClassInterceptorsDisabled { get; set; }
}
abp autofac 添加服务的时候配置属性注入和拦截器
使用 autofac ConfigureAbpConventions 注册服务的时候,添加拦截器属性注入
禁用属性注入
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
public class DisablePropertyInjectionAttribute : Attribute
{
}
public static class AbpRegistrationBuilderExtensions
{
//registrationBuilder 添加的扩展方法用于添加拦截器属性注入
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
ConfigureAbpConventions<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
registrationBuilder,
IModuleContainer moduleContainer,
ServiceRegistrationActionList registrationActionList)
where TActivatorData : ReflectionActivatorData
{
//没有服务类型,只有对象注入,对象就是服务类型
var serviceType = registrationBuilder.RegistrationData.Services.
OfType<IServiceWithType>().FirstOrDefault()?.ServiceType;
if (serviceType == null)
{
return registrationBuilder;
}
//没有实现的类型,退出
var implementationType = registrationBuilder.ActivatorData.ImplementationType;
if (implementationType == null)
{
return registrationBuilder;
}
//属性注入
registrationBuilder = registrationBuilder.EnablePropertyInjection(
moduleContainer, implementationType);
//注册拦截器 registrationActionList 用户添加的注入服务及其绑定的拦截器类型
registrationBuilder = registrationBuilder.InvokeRegistrationActions(
registrationActionList, serviceType, implementationType);
return registrationBuilder;
}
//注册拦截器
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
InvokeRegistrationActions<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
registrationBuilder,
ServiceRegistrationActionList registrationActionList,
Type serviceType,
Type implementationType)
where TActivatorData : ReflectionActivatorData
{
//生成一个上下文
var serviceRegistredArgs = new OnServiceRegistredContext(serviceType,
implementationType);
//通过 action 给上下文 serviceRegistredArgs 添加拦截器,执行委托进行设置
foreach (var registrationAction in registrationActionList)
{
registrationAction.Invoke(serviceRegistredArgs);
}
//注册拦截器到类型
if (serviceRegistredArgs.Interceptors.Any())
{
registrationBuilder = registrationBuilder.AddInterceptors(
registrationActionList,
serviceType,
serviceRegistredArgs.Interceptors
);
}
return registrationBuilder;
}
//属性注入
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
EnablePropertyInjection<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
registrationBuilder,
IModuleContainer moduleContainer,
Type implementationType)
where TActivatorData : ReflectionActivatorData
{
// 属性注入的的类型所在的程序集必须在模块范围内的程序集
if (moduleContainer.Modules.Any(m => m.Assembly == implementationType.Assembly) &&
implementationType.GetCustomAttributes(
typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty())
{
//注入属性,使用属性默认的属性选择器,属性注入必要要是 public 支持 set方法的属性
// DefaultPropertySelector : IPropertySelector
registrationBuilder = registrationBuilder.PropertiesAutowired(
new AbpPropertySelector(false));
}
return registrationBuilder;
}
//对服务类或接口和拦截器进行绑定的过程 通过 IRegistrationBuilder 进行绑定
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
AddInterceptors<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
registrationBuilder,
ServiceRegistrationActionList serviceRegistrationActionList,
Type serviceType,
IEnumerable<Type> interceptors)
where TActivatorData : ReflectionActivatorData
{
if (serviceType.IsInterface)
{
//接口拦截
registrationBuilder = registrationBuilder.EnableInterfaceInterceptors();
}
else
{
//禁用类拦截器
if (serviceRegistrationActionList.IsClassInterceptorsDisabled)
{
return registrationBuilder;
}
//类拦截
(registrationBuilder as IRegistrationBuilder<TLimit,
ConcreteReflectionActivatorData, TRegistrationStyle>)?.EnableClassInterceptors();
}
//注册拦截器,一个组件注册了多个拦截器
foreach (var interceptor in interceptors)
{
//在注册组件的时候使用拦截器
registrationBuilder.InterceptedBy(
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptor)
);
}
return registrationBuilder;
}
//配置类拦截或接口拦截
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
AddInterceptors<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder,
ServiceRegistrationActionList serviceRegistrationActionList,
Type serviceType,
IEnumerable<Type> interceptors)
where TActivatorData : ReflectionActivatorData
{
if (serviceType.IsInterface)
{
//接口拦截
registrationBuilder = registrationBuilder.EnableInterfaceInterceptors();
}
else
{
//类拦截器可以禁用,毕竟写虚方法比较麻烦
if (serviceRegistrationActionList.IsClassInterceptorsDisabled)
{
return registrationBuilder;
}
//类拦截
(registrationBuilder as IRegistrationBuilder<
TLimit, ConcreteReflectionActivatorData, TRegistrationStyle>)
?.EnableClassInterceptors();
}
foreach (var interceptor in interceptors)
{
registrationBuilder.InterceptedBy(
//把 abp 的拦截器转换为 AbpAsyncDeterminationInterceptor ,
//在转为 AsyncDeterminationInterceptor 在转为 castle 的 Interceptor
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptor)
);
}
return registrationBuilder;
}
}
public class AbpPropertySelector : DefaultPropertySelector
{
public AbpPropertySelector(bool preserveSetValues)
: base(preserveSetValues)
{
}
public override bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
return propertyInfo.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute),
true).IsNullOrEmpty() &&
base.InjectProperty(propertyInfo, instance);
}
}
IAvoidDuplicateCrossCuttingConcerns
横切关注点如何做到不重复
abp 定义继承此接口的服务类,应用了横切关注,可以避免横切关注点会重复执行
public interface IAvoidDuplicateCrossCuttingConcerns
{
List<string> AppliedCrossCuttingConcerns { get; }
}
用来记录相关的拦截器或过滤器是否已经被拦截过了方法
public static class AbpCrossCuttingConcerns
{
public const string Auditing = "AbpAuditing";
public const string UnitOfWork = "AbpUnitOfWork";
public const string FeatureChecking = "AbpFeatureChecking";
public const string GlobalFeatureChecking = "AbpGlobalFeatureChecking";
public static void AddApplied(object obj, params string[] concerns)
{
if (concerns.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(concerns), $"{nameof(concerns)}
should be provided!");
}
(obj as IAvoidDuplicateCrossCuttingConcerns)?.AppliedCrossCuttingConcerns.
AddRange(concerns);
}
public static void RemoveApplied(object obj, params string[] concerns)
{
if (concerns.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(concerns), $"{nameof(concerns)}
should be provided!");
}
var crossCuttingEnabledObj = obj as IAvoidDuplicateCrossCuttingConcerns;
if (crossCuttingEnabledObj == null)
{
return;
}
foreach (var concern in concerns)
{
crossCuttingEnabledObj.AppliedCrossCuttingConcerns.RemoveAll(c => c == concern);
}
}
public static bool IsApplied([NotNull] object obj, [NotNull] string concern)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(obj));
}
if (concern == null)
{
throw new ArgumentNullException(nameof(concern));
}
return (obj as IAvoidDuplicateCrossCuttingConcerns)?.AppliedCrossCuttingConcerns.
Contains(concern) ?? false;
}
public static IDisposable Applying(object obj, params string[] concerns)
{
AddApplied(obj, concerns);
return new DisposeAction<ValueTuple<object, string[]>>(static (state) =>
{
var (obj, concerns) = state;
RemoveApplied(obj, concerns);
}, (obj, concerns));
}
public static string[] GetApplieds(object obj)
{
var crossCuttingEnabledObj = obj as IAvoidDuplicateCrossCuttingConcerns;
if (crossCuttingEnabledObj == null)
{
return new string[0];
}
return crossCuttingEnabledObj.AppliedCrossCuttingConcerns.ToArray();
}
}
public const string Auditing = "AbpAuditing";
public const string UnitOfWork = "AbpUnitOfWork";
public const string FeatureChecking = "AbpFeatureChecking";
public const string GlobalFeatureChecking = "AbpGlobalFeatureChecking";
单独分析审计日志
过滤器审计日志
public const string Auditing = "AbpAuditing";
public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context,
ActionExecutionDelegate next)
{
if (!ShouldSaveAudit(context, out var auditLog, out var auditLogAction))
{
await next();
return;
}
//当代码执行到这里的时候,加入 AbpCrossCuttingConcerns 加入标记
using (AbpCrossCuttingConcerns.Applying(context.Controller,
AbpCrossCuttingConcerns.Auditing))
{
var stopwatch = Stopwatch.StartNew();
try
{
var result = await next();
if (result.Exception != null && !result.ExceptionHandled)
{
auditLog.Exceptions.Add(result.Exception);
}
}
catch (Exception ex)
{
auditLog.Exceptions.Add(ex);
throw;
}
finally
{
stopwatch.Stop();
if (auditLogAction != null)
{
auditLogAction.ExecutionDuration = Convert.ToInt32(
stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
}
}
}
}
}
拦截器审计日志
public class AuditingInterceptor : AbpInterceptor, ITransientDependency{
private readonly IServiceScopeFactory _serviceScopeFactory;
public AuditingInterceptor(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
using (var serviceScope = _serviceScopeFactory.CreateScope())
{
var auditingHelper = serviceScope.ServiceProvider.
GetRequiredService<IAuditingHelper>();
var auditingOptions = serviceScope.ServiceProvider.
GetRequiredService<IOptions<AbpAuditingOptions>>().Value;
if (!ShouldIntercept(invocation, auditingOptions, auditingHelper))
{
await invocation.ProceedAsync();
return;
}
var auditingManager = serviceScope.ServiceProvider.
GetRequiredService<IAuditingManager>();
if (auditingManager.Current != null)
{
await ProceedByLoggingAsync(invocation, auditingOptions,
auditingHelper, auditingManager.Current);
}
else
{
var currentUser = serviceScope.ServiceProvider.
GetRequiredService<ICurrentUser>();
var unitOfWorkManager = serviceScope.ServiceProvider.
GetRequiredService<IUnitOfWorkManager>();
await ProcessWithNewAuditingScopeAsync(
invocation, auditingOptions, currentUser,
auditingManager, auditingHelper, unitOfWorkManager);
}
}
}
protected virtual bool ShouldIntercept(IAbpMethodInvocation invocation,
AbpAuditingOptions options,
IAuditingHelper auditingHelper)
{
if (!options.IsEnabled)
{
return false;
}
//因为是过滤器先执行,过滤器标记了,拦截器就不记录日志了
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject,
AbpCrossCuttingConcerns.Auditing))
{
return false;
}
if (!auditingHelper.ShouldSaveAudit(
invocation.Method,
ignoreIntegrationServiceAttribute:
options.IsEnabledForIntegrationServices))
{
return false;
}
return true;
}
}
subtle difference
OnExposing
导出 ExposeServicesAttribute ,获取可导出的服务类型或接口
public class ExposeServicesAttribute : Attribute, IExposedServiceTypesProvider
{
public Type[] ServiceTypes { get; }
public bool IncludeDefaults { get; set; }
public bool IncludeSelf { get; set; }
//配置的导出类型,人为指定的
public ExposeServicesAttribute(params Type[] serviceTypes)
{
ServiceTypes = serviceTypes ?? Type.EmptyTypes;
}
public Type[] GetExposedServiceTypes(Type targetType)
{
var serviceList = ServiceTypes.ToList();
if (IncludeDefaults)
{
foreach (var type in GetDefaultServices(targetType))
{
serviceList.AddIfNotContains(type);
}
if (IncludeSelf)
{
serviceList.AddIfNotContains(targetType);
}
}
//导出对象本身
else if (IncludeSelf)
{
serviceList.AddIfNotContains(targetType);
}
return serviceList.ToArray();
}
//缺省的是 接口类是IBar 如果实现类的命名是 Bar,或 MyBar ,那么导出的接口就是 IBar
private static List<Type> GetDefaultServices(Type type)
{
var serviceTypes = new List<Type>();
foreach (var interfaceType in type.GetTypeInfo().GetInterfaces())
{
var interfaceName = interfaceType.Name;
if (interfaceType.IsGenericType)
{
interfaceName = interfaceType.Name.Left(interfaceType.Name.IndexOf('`'));
}
if (interfaceName.StartsWith("I"))
{
interfaceName = interfaceName.Right(interfaceName.Length - 1);
}
if (type.Name.EndsWith(interfaceName))
{
serviceTypes.Add(interfaceType);
}
}
return serviceTypes;
}
}
在导出服务类型的时候人为的进行干预
导出时注册的 action 可以影响注册服务
public class ServiceExposingActionList : List<Action<IOnServiceExposingContext>>
{
}
namespace Volo.Abp.DependencyInjection;
//一个实现类及多个导出的接口
public class OnServiceExposingContext : IOnServiceExposingContext
{
public Type ImplementationType { get; }
public List<Type> ExposedTypes { get; }
public OnServiceExposingContext([NotNull] Type implementationType,
List<Type> exposedTypes)
{
ImplementationType = Check.NotNull(implementationType,
nameof(implementationType));
ExposedTypes = Check.NotNull(exposedTypes, nameof(exposedTypes));
}
}
public static class ServiceCollectionRegistrationActionExtensions
{
public static void OnExposing(this IServiceCollection services,
Action<IOnServiceExposingContext> exposeAction)
{
GetOrCreateExposingList(services).Add(exposeAction);
}
//导出时的 action 保存在 IObjectAccessor<ServiceExposingActionList> 里
private static ServiceExposingActionList GetOrCreateExposingList(IServiceCollection services)
{
var actionList = services.GetSingletonInstanceOrNull<
IObjectAccessor<ServiceExposingActionList>>()?.Value;
if (actionList == null)
{
actionList = new ServiceExposingActionList();
services.AddObjectAccessor(actionList);
}
return actionList;
}
}
ConventionalRegistrarBase
约定注册 base 类
public abstract class ConventionalRegistrarBase : IConventionalRegistrar
{
protected virtual void TriggerServiceExposing(IServiceCollection services,
Type implementationType, List<Type> serviceTypes)
{
var exposeActions = services.GetExposingActionList();
if (exposeActions.Any())
{
//服务注册的时候,传入的实现类及导出的类型
var args = new OnServiceExposingContext(implementationType, serviceTypes);
//注册的所有 action
foreach (var action in exposeActions)
{
//执行action ,导出的类型 serviceTypes 数量会受影响
action(args);
}
}
}
}
public class DefaultConventionalRegistrar : ConventionalRegistrarBase
{
public override void AddType(IServiceCollection services, Type type)
{
if (IsConventionalRegistrationDisabled(type))
{
return;
}
var dependencyAttribute = GetDependencyAttributeOrNull(type);
var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute);
if (lifeTime == null)
{
return;
}
//获取此实现类的所有导出类型集合
var exposedServiceTypes = GetExposedServiceTypes(type);
//触发导出 action,导出类型集合在此过程中可以添加或减少
TriggerServiceExposing(services, type, exposedServiceTypes);
//注册
foreach (var exposedServiceType in exposedServiceTypes)
{
var serviceDescriptor = CreateServiceDescriptor(
type,
exposedServiceType,
exposedServiceTypes,
lifeTime.Value
);
if (dependencyAttribute?.ReplaceServices == true)
{
services.Replace(serviceDescriptor);
}
else if (dependencyAttribute?.TryRegister == true)
{
services.TryAdd(serviceDescriptor);
}
else
{
services.Add(serviceDescriptor);
}
}
}
}
ConfigureServices 源码验证
BuildServiceProvider
BuildServiceProvider 内部是 copy 当前的 Service Collection,生成的
public override void ConfigureServices(ServiceConfigurationContext context) {
context.Services.AddTransient<ISpecificF, SpecificF>();
//拷贝当前的 Service Collection,生成 serviceProvider
var serviceProvider = context.Services.BuildServiceProvider();
//此时可以获取到 SpecificF
var specificF = serviceProvider.GetService<ISpecificF>();
}
public override void ConfigureServices(ServiceConfigurationContext context) {
//拷贝当前的 Service Collection ,生成 serviceProvider
var serviceProvider = context.Services.BuildServiceProvider();
//此后在加入 Service Collection 的集合,通过 serviceProvider 不能访问到
context.Services.AddTransient<ISpecificF, SpecificF>();
//此时获取不到 SpecificF
var specificF = serviceProvider.GetService<ISpecificF>(); //null
}
ContainerBuilder 在服务注册阶段和 asp.net core 是隔离的
public override void ConfigureServices(ServiceConfigurationContext context) {
var serviceProvider = context.Services.BuildServiceProvider();
var containerBuilder= serviceProvider.
GetRequiredService<IObjectAccessor<ContainerBuilder>>()?.Value;
containerBuilder?.RegisterType<SpecificF>().As<ISpecificF>();
// 在服务配置阶段的 ServiceProvider 解析服务引擎使用的是 asp.net core
// Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine
// 替换引擎要在 WebApplication build 的时候 var app = builder.Build();
// 所以这里是不能获取到 autofac 里注入的服务的
var serviceProvider1 = context.Services.BuildServiceProvider();
var specificF = serviceProvider1.GetService<ISpecificF>(); //null
//通过 autofac 引擎可以获取,但是不要通过 build 去执行,因为 build 内部是 通过
// AbpAutofacServiceProviderFactory 执行,一旦执行过就不能在执行了,因为只允许一个根容器存在
specificF= containerBuilder.Build().Resolve<ISpecificF>(); // 👍
}
服务注册结束,就不能继续注入
public override void OnApplicationInitialization(
ApplicationInitializationContext context) {
//引擎替换工作已经完成 serviceProvider 替换为
// Autofac.Extensions.DependencyInjection.AutofacServiceProvider
var serviceProvider = context.ServiceProvider;
var containerBuilder= serviceProvider.GetRequiredService<
IObjectAccessor<ContainerBuilder>>()?.Value;
//在服务注册阶段完成后,通过 autofac 注入的服务也无法获取到
containerBuilder?.RegisterType<Foo>().As<IFoo>();
//获取通过 containerBuilder 注册的服务
var specificF= serviceProvider.GetService<ISpecificF>();
//无法获取
var foo= serviceProvider.GetService<IFoo>(); // null
}
var app = builder.Build();
//Build app 的第一件事情是挂载 abp 的服务,要不注入会失败
await app.InitializeApplicationAsync();
//在 build 后继续注入服务,会抛出错误
builder.Services.AddTransient<IFoo, Foo>();
var foo=app.Services.GetService<IFoo>();
public IHost Build()
{
if (_hostBuilt)
{
throw new InvalidOperationException(SR.BuildCalled);
}
_hostBuilt = true;
using DiagnosticListener diagnosticListener = HostBuilder.LogHostBuilding(this);
_hostBuilderAdapter?.ApplyChanges();
_appServices = _createServiceProvider();
// Prevent further modification of the service collection now
//that the provider is built.
//因为 build 后, serviceCollection 就是只读了,不能做任何修改 ,修改就抛出错误
_serviceCollection.MakeReadOnly();
return HostBuilder.ResolveHost(_appServices, diagnosticListener);
}