abp vnext 启动,加载module,依赖注入源码分析
2022/2/18 22:41:47
本文主要是介绍abp vnext 启动,加载module,依赖注入源码分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
- Program类 IHostBuilder UseAutofac(this IHostBuilder hostBuilder)扩展方法
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);
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里实现的内容
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
//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); } }
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方法
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里面
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(); }
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
例:
//获取到的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
这篇关于abp vnext 启动,加载module,依赖注入源码分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-26大厂数据结构与算法教程:入门级详解
- 2024-12-26大厂算法与数据结构教程:新手入门指南
- 2024-12-26Python编程入门指南
- 2024-12-26数据结构高级教程:新手入门及初级提升指南
- 2024-12-26并查集入门教程:从零开始学会并查集
- 2024-12-26大厂数据结构与算法入门指南
- 2024-12-26大厂算法与数据结构入门教程
- 2024-12-26二叉树入门教程:轻松掌握基础概念与操作
- 2024-12-26初学者指南:轻松掌握链表
- 2024-12-26平衡树入门教程:轻松理解与应用