abp vnext 启动,加载module,依赖注入源码分析
- Program类 IHostBuilder UseAutofac(this IHostBuilder hostBuilder)扩展方法
1234567891011
public
static
IHostBuilder UseAutofac(
this
IHostBuilder hostBuilder)
{
//创建一个Autofac容器,后面会通过BuildServiceProviderFromFactory方法调AbpAutofacServiceProviderFactory里的CreateBuilder方法替换IOC容器
var
containerBuilder =
new
ContainerBuilder();
return
hostBuilder.ConfigureServices((_, services) =>
{
services.AddObjectAccessor(containerBuilder);
})
.UseServiceProviderFactory(
new
AbpAutofacServiceProviderFactory(containerBuilder));
}
- Startup里services.AddApplication<>();方法
里面调AbpApplicationFactory.Create<TStartupModule>(services, optionsAction);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public static class AbpApplicationFactory { //控制台应用程序new AbpApplicationWithInternalServiceProvider:AbpApplicationBase //apiservice new AbpApplicationWithExternalServiceProvider:AbpApplicationBase public static IAbpApplicationWithInternalServiceProvider Create<TStartupModule>( [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null ) where TStartupModule : IAbpModule { return Create( typeof (TStartupModule), optionsAction); } public static IAbpApplicationWithInternalServiceProvider Create( [NotNull] Type startupModuleType, [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null ) { return new AbpApplicationWithInternalServiceProvider(startupModuleType, optionsAction); } public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>( [NotNull] IServiceCollection services, [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null ) where TStartupModule : IAbpModule { return Create( typeof (TStartupModule), services, optionsAction); } public static IAbpApplicationWithExternalServiceProvider Create( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null ) { return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction); } } |
3.AbpApplicationBase里实现的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | internal AbpApplicationBase( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction) { Check.NotNull(startupModuleType, nameof(startupModuleType)); Check.NotNull(services, nameof(services)); StartupModuleType = startupModuleType; Services = services; //往ObjectAccessor里添加一个IServiceProvider,后面ApplicationInitializationContext.ServiceProvider拿出来用 services.TryAddObjectAccessor<IServiceProvider>(); //在services.AddApplication<AbpExceptionDemoModule>(option=》{});里赋值AbpApplicationCreationOptions var options = new AbpApplicationCreationOptions(services); optionsAction?.Invoke(options); services.AddSingleton<IAbpApplication>( this ); services.AddSingleton<IModuleContainer>( this ); //注入abp一些基础组件 services.AddCoreServices(); //注入模块相关组件 services.AddCoreAbpServices( this , options); //将一些模块添加到集合,先添加[DependsOn]里的模块,再添加里赋值AbpApplicationCreationOptions.PlugInSources里的模块 Modules = LoadModules(services, options); //按顺序加载Modules ConfigureServices(); } |
4.ConfigureServices里实现的内容,遍历Modules执行PreConfigureServices方法,依次遍历Modules执行ConfigureServices,PostConfigureServices后清空ServiceConfigurationContext属性
5.关于遍历Modules执行ConfigureServices
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //ConfigureServices foreach ( var module in Modules) { if (module.Instance is AbpModule abpModule) { if (!abpModule.SkipAutoServiceRegistration) { //在这里拉module所在程序集里的接口,类,按规则注入 Services.AddAssembly(module.Type.Assembly); } } try { module.Instance.ConfigureServices(context); } catch (Exception ex) { throw new AbpInitializationException($ "An error occurred during {nameof(IAbpModule.ConfigureServices)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details." , ex); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public abstract class ConventionalRegistrarBase : IConventionalRegistrar { public virtual void AddAssembly(IServiceCollection services, Assembly assembly) { //筛选非抽象类,泛型类,在ConventionalRegistrarList(DefaultConventionalRegistrar)里的方法依次执行AddType方法 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); |
6.看下DefaultConventionalRegistrar里的AddType方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public override void AddType(IServiceCollection services, Type type) { //判断是否有DisableConventionalRegistrationAttribu特性 if (IsConventionalRegistrationDisabled(type)) { return ; } //获取DependencyAttribute特性 var dependencyAttribute = GetDependencyAttributeOrNull(type); //dependencyAttribute.Lifetime有值就用dependencyAttribute的注入方式,否则就用ITransientDependency等接口 var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute); if (lifeTime == null ) { return ; } // 获得等待注册的类型定义,类型的定义优先使用 ExposeServices 特性指定的类型,如果没有则使用 // 类型当中接口以 I 开始,后面为实现类型名称的接口。 var exposedServiceTypes = GetExposedServiceTypes(type); TriggerServiceExposing(services, type, exposedServiceTypes); foreach ( var exposedServiceType in exposedServiceTypes) { //创建一个注入描述 var serviceDescriptor = CreateServiceDescriptor( type, exposedServiceType, exposedServiceTypes, lifeTime.Value ); //判断是替换注入对象还是tryAdd,add if (dependencyAttribute?.ReplaceServices == true ) { services.Replace(serviceDescriptor); } else if (dependencyAttribute?.TryRegister == true ) { services.TryAdd(serviceDescriptor); } else { services.Add(serviceDescriptor); } } } |
7.GetExposedServiceTypes方法获取实现类与实现类的接口,后面一起注入IServiceCollection里面
1 2 3 4 5 6 7 8 9 10 | public static List<Type> GetExposedServices(Type type) { return type .GetCustomAttributes( true ) .OfType<IExposedServiceTypesProvider>() //获取type中ExposedService特性里面的types .DefaultIfEmpty(DefaultExposeServicesAttribute) .SelectMany(p => p.GetExposedServiceTypes(type)) //用GetExposedServiceTypes()处理types .Distinct() .ToList(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public Type[] GetExposedServiceTypes(Type targetType) { var serviceList = ServiceTypes.ToList(); if (IncludeDefaults) //目前属性没开放出来,默认true { foreach ( var type in GetDefaultServices(targetType)) //获取该接口与实现类除首字母I外是否相等,serviceList添加type { serviceList.AddIfNotContains(type); } if (IncludeSelf) //目前属性没开放出来,默认true { serviceList.AddIfNotContains(targetType); //添加自己 } } else if (IncludeSelf) { serviceList.AddIfNotContains(targetType); } return serviceList.ToArray(); } private static List<Type> GetDefaultServices(Type type) { var serviceTypes = new List<Type>(); foreach ( var interfaceType in type.GetTypeInfo().GetInterfaces()) { var interfaceName = interfaceType.Name; if (interfaceName.StartsWith( "I" )) { interfaceName = interfaceName.Right(interfaceName.Length - 1); } if (type.Name.EndsWith(interfaceName)) { serviceTypes.Add(interfaceType); } } return serviceTypes; } |
8.可以看到GetExposedServices()获取的是:实现类及 除首字母I外name与他相等的接口和IExposedService特性里的types
例:
1 2 3 4 | //获取到的ServiceTypes里的内容是IBTestService,ITestService,TestService //后面会依次注入这3个类型 [ExposeServices( typeof (IBTestService))] public class TestService: ITestService:IMyTestService |
参考:https://www.cnblogs.com/zhiyong-ITNote/archive/2019/12/08/12005772.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?